如何在F#中创建包含可变,易变的int64的高速缓存行大小的结构?

时间:2015-08-16 21:00:12

标签: f#

我想创建一个缓存行大小的结构,在F#中包装一个可变的,易变的int64。我已经尝试了各种结构定义,包括下面的那个,但是无法编译任何内容。

[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct1 (initVal:int64) =
    [<VolatileField>]
    let mutable value = initVal
    member x.Value 
        with get () = value
        and set(valIn) = value <- valIn

给出了这个错误:“结构不能包含值定义,因为结构的默认构造函数不会执行这些绑定。 考虑在类型“的主要构造函数中添加其他参数。我无法看到我可以在上面的主要构造函数中添加哪些其他参数。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

struct定义可能是

[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct =
    [<FieldOffset(0)>]
    val mutable value : int64
    new(initVal:int64) = { value = initVal }
    member x.Value
        with get() = x.value
        and set(valIn) = x.value <- valIn

但是,在val绑定和结构can't contain let bindings上不允许[<VolatileField>]

TL; DR:AFAIK 在F#中是不可能的

正如@ V.B所指出的那样。你可以使用Interlocked给出volatile s保证的超集(更强的保证≈更多的开销)。然后private ize value可以更好地防止(意外)写入绕过障碍:

[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct =
    [<FieldOffset(0)>]
    val mutable private value : int64
    new(initVal:int64) = { value = initVal }
    member public x.Value
        with get() = Interlocked.Read(&x.value)
        and set(valIn) = Interlocked.Exchange(&x.value, valIn) |> ignore

答案 1 :(得分:0)

Interlocked提供与volatile类似的保证,请参阅this question

open System.Threading
[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct =
    [<FieldOffset(0)>]
    val mutable value : int64
    new(initVal:int64) = { value = initVal }
    member x.Value
        with get() = Interlocked.Read(&(x.value))
        and set(valIn) = Interlocked.Exchange(&(x.value),valIn) |> ignore