1

2GB 以上の RAM を割り当てられることを同僚に示したかったので、ちょっとしたテスト アプリケーションを作成しました。

let mega = 1 <<< 20
let konst x y = x
let allocate1MB _ = Array.init mega (konst 0uy)
let memoryHog = Array.Parallel.init 8192 allocate1MB

printfn "I'm done..."
System.Console.ReadKey() |> ignore

これは機能し、プロセスがシステムのメモリを喜んで占有しているのを実際に確認できます。ただし、多少時間がかかるため、Array.Parallel.init.

私は、同じコードが機能しないことに気付きました。

let allocate1MB _ = Array.zeroCreate mega

より正確には、データは割り当てられず、時間もかかりません。

したがって、私の質問です。Array.zeroCreate と Array.init のセマンティクスの違いは何ですか?

毎回関数Array.initが実行されることを理解しています。これにより、時間差が説明されます。konst 0uyしかし、なぜArray.zeroCreateメモリを割り当てないのですか?

4

3 に答える 3

0

あなたの直接の質問に答える:Array.zeroCreate型のデフォルト値の要素のArray.init配列を作成し、提供されたジェネレーター関数を使用して要素の配列を作成して、それぞれを作成します。Array.zeroCreateの対応するジェネレータ関数を使用して、 のセマンティクスをいつでも実装できますArray.init

-値の型の場合、例byte:

> let az: byte [] = Array.zeroCreate 1;;
val az : byte [] = [|0uy|]
> let ai = Array.init 1 (fun _ -> 0uy);;
val ai : byte [] = [|0uy|]

-参照型の場合、例string:

> let az: string [] = Array.zeroCreate 1;;
val az : string [] = [|null|]
> let ai = Array.init 1 (fun _ -> Unchecked.defaultof<string>);;
val ai : string [] = [|null|]

ここで、この観察結果を 2GB を超える RAM を割り当てるという元の問題に適用すると、Array.zeroCreate.NET 4.5 および 64 ビット OSで の構成有効gcAllowVeryLargeObjectsfsiAnyCPU.exeにした後、このような割り当てを行うことができます。以下の 1 行のコードは、すぐにの配列に約8GBの RAM を割り当てます。int

> let bigOne: int [] = Array.zeroCreate 2146435071

そして、以下はこれが機能したことを証明しています:

> bigOne.[2146435070] <- 1
val it : unit = ()
> bigOne.[2146435070]
val it : int = 1
于 2013-10-07T17:08:04.867 に答える