我々缶p
がnativeptr<'a>
あるのでSystem.Numerics.Vectorにnativeptr <T>から読み出し<T>チャンクF#の
open FSharp.NativeInterop
let x = NativePtr.read p
ようなタイプ'a
の値を指し示すポインタ間接参照。
このポインタが'a
値の配列を指しており、System.Numerics.Vector<_>
でSIMDを使用してこの配列を処理したいとします。そのためにはnの連続した'a
の値をVector<'a>
構造体にロードする必要があります。 .NET /マネージド配列の場合、これは適切なVector<_>
コンストラクタを使用することで実現できます。しかし残念ながら、ポインタ(実際には、この特定のケースではアンマネージヒープを指しています)が存在するため、既存のコンストラクタオーバーロードのいずれかを使用することはできません。
p
をnativeptr<Vector<'a>>
と再解釈するのはどうですか? Vector<_>
、as a generic data typeは、ない - nativeptr
の型パラメータがunmanaged
制約を満たすために持っているので、
let inline cast<'T, 'U when 'U : unmanaged and 'T: unmanaged> (ptr: nativeptr<'T>) =
ptr |> NativePtr.toNativeInt |> NativePtr.ofNativeInt<'U>
let v = p |> NativePtr.cast<'a, Vector<'a>> |> NativePtr.read
悲しいことに、これは、worktしません。
unmanaged
の制約がC#コンパイラによって強制されないため、この問題を回避する1つの方法は、NativeInteropと組み合わせてC#を使用することです。しかし、私は本当にF#に泊まりたいです。
F#から効率的に働くことができますか?または、Vector<_>
がポインターからのロードをサポートするコンストラクターで拡張されるのを待つ唯一のオプションはありますか?
C#コンパイラを使用しても、生のメモリを特定の種類のオブジェクトとして「再解釈」することはできません。これはC言語ではありません。 CLR型は単にコンパイル時の構造だけでなく、ランタイム表現も持っています。その「管理されていない」制約が理由のためにあります。 –
[もちろん私は](https://gist.github.com/FrankNiemeyer/38f376e78fdc53cf3246deb7822b959a)(これまで説明したように、C#コンパイラは "let me"を実行しますが、F#compは実行しません)。 'Vector'はblittable( 'T'はプリミティブ型だけがサポートされているので常に管理されていません)であり、メモリ上で128(SSE)または256ビット(AVX)のSIMDストライドにまで下がります。それ。 –
Frank
あなたのプログラムはあなたが思うとは思わないと思います。その 'IntPtr.Read'拡張メソッドは、メモリを' Vector 'として「再解釈」しません。実際には、いくつかのバイトを新しい場所にコピーします。 –