私は最適化したい64ビットアセンブリを作成していますが、データを渡すための「適切な方法」ネイティブコードに変換されます。複雑な.NETデータをネイティブ(アセンブリコード)に渡す
データが.net側で生成されるため、asm側でデータを割り当てることはオプションではありません。
それは契約ブレーカませんが、直接.NET =>ネイティブDLLソリューションがある場合、私はむしろC++/CLIを避けるだろう
私が渡したいデータはで返されるものと同様の形式でありますこのクエリ:
var q = Enumerable.Range(bla)
.Where(bla)
.Select(item=>very complex and cpu intensive query and subqueries)
.Select(item=> new
{
a=item.a,
b=item.b,
c=item.c,
d=item.d,
e=item.e,
f=item.f
}).ToArray();
これを最初にコピーすることなくネイティブコードに渡す方法はありますか?私が見つけたのは、2つの欠点を持つ解決策でした。
1)データをコピーする必要があります(それはRAMの使用量を考慮すると安価な操作ではなく、100GB以上のRAMを使用しています。 !) 2)現在、私はこのようhavelooks多分これは、非匿名の種類とstructlayoutsを軽減することができた(データを平坦化)
必要です:
var array = Enumerable.Range(bla)
.Where(bla)
.Select(item=>very complex and cpu intensive query and subqueries)
.SelectMany(item=> new int[]
{
item.a,
item.b,
item.c,
item.d,
item.e,
item.f
}).ToArray();
int size = Marshal.SizeOf(array[0]) * array.Length;
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(array, 0, ptr, array.Length);
ことを取り除くために方法はありますか?追加の割り当てと多くのRAMを節約できますか?私は本当にパフォーマンスとメモリ使用の理由の両方のために、実際のメモリとコピーではなく、使用することが大好きです。
残りのコードをアセンブリに移植することは、あまりにも複雑で、CPUが集中する間はボトルネックではありません。
今やギザギザの配列があります。 * struct *を宣言すると、より効率的になります。しかし、100ギガバイトはあまりにも多く、それは適合しません。実際には、今のところフィットしません。そのギザギザの配列は、それほど多くの要素を持つことはできません。だから多分あなたの要件は想像されており、実用的な考慮に基づいていません。 –
@HansPassant私はギザギザの配列を持っていない、それはselectmanyによって平坦化されている、それはフラットな配列です、またはあなたが何を言っているのを忘れていますか? –