関連記事
- 【#CSHARP】ソリューション内でサービス,Winformアプリを混在で作成させ,バイナリ出力先を同じにするとサービスが起動しない 【2024年02月08日(木)】
- 【#PHP】謎な #Laravel 案件 引き渡したじ 【2024年01月11日(木)】
- 【C#】謎な改造アプリ,SIMD命令を導入して高速化しようか,思案中 【2023年11月14日(火)】
- Javaの”やらかし”でC#と人気逆転か 激変プログラミング言語人気ランキング 【2023年10月18日(水)】
- 【#CSHARP】次の案件のスケルトン書いてgitサーバに登録するなどと 【2023年05月16日(火)】
IntPtrバッファからIntPtrバッファへのコピーをもっと楽な方法でやれんのかと
いろいろ探していたら…
いろいろなパターンでのメモリーコピーの速度テストのサンプル@C#を見つけたり
参考にしたのは,こちら
gamedev.net
Marshal.Copy()を利用する方法
unsafeに入って,ポインタ抜き出して,
byte,int,long,構造体を利用した巨大メモリブロック
をループでコピーする方法が記述されており
んで,こっちで,RtlMoveMemory()@Win32APIを利用するパターンを追加してみたり
条件は以下のとおり
CPU : Intel Core2Quad Q6600(2.4GHz)
Memory : 2GB
OS : Windows XP Pro
言語: Visual Studio 2005(C#2.0) + .Net FrameWork2.0
さきに,実行結果を書いちゃうけど…
-
Performing tests on copying 1024 kilobytes of memory.
Average time for Marshal is 0.29 ms.
Average time for API is 0.14 ms. Average time byte copy is 4.89 ms.
Average time int copy is 1.24 ms.
Average time long copy is 0.7 ms.
Average time copystruct2 copy is 0.36 ms.
Average time copystruct4 copy is 0.5 ms.
Average time copystruct16 copy is 0.23 ms.
Average time copystruct128 copy is 0.15 ms.
Marshal.Copy()は,IntPtr->byte配列 byte配列->IntPtrの2回のコピー作業をやっているんで
まぁ,APIと速度は変わらんか
でも,IntPtr->IntPtrはMarshal.Copy()にオーバーロードが準備されて無いしのぉ~
ってことで,RtlMoveMemory()APIをメインで使っていくことに決定!
ソースはこちら
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestCS
{
class Program
{
#region APIs
[DllImport(“Kernel32.dll”, EntryPoint=”RtlMoveMemory”)]
private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length);
#endregion
unsafe struct copystruct2
{
fixed long l[2];
}
unsafe struct copystruct4
{
fixed long l[4];
}
unsafe struct copystruct16
{
fixed long l[16];
}
unsafe struct copystruct128
{
fixed long l[128];
}
unsafe static void Main(string[] args)
{
const int size = 1048576;
const int count = 100;
IntPtr ptr = Marshal.AllocHGlobal(size);
IntPtr ptr2 = Marshal.AllocHGlobal(size);
byte[] bytes = new byte[size];
Console.WriteLine(“Performing tests on copying {0} kilobytes of memory.”,
size / (double)1024);
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
// make sure methods are JIT’d (they probably are, since there
// should be native images of the standard library, but just to be safe..)
watch.Reset();
watch.Start();
watch.Stop();
Marshal.Copy(bytes, 0, ptr, size);
Marshal.Copy(ptr2, bytes, 0, size);
watch.Reset();
watch.Start();
for (int i = 0; i < count; i++)
{
Marshal.Copy(bytes, 0, ptr, size);
Marshal.Copy(ptr2, bytes, 0, size);
}
watch.Stop();
double averageTime = watch.ElapsedMilliseconds / (double)count;
Console.WriteLine("Average time for Marshal is {0} ms.", averageTime);
watch.Reset();
watch.Start();
for (int i = 0; i < count; i++)
{
CopyMemory(ptr2, ptr, size);
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
Console.WriteLine("Average time for API is {0} ms.", averageTime);
{
watch.Reset();
watch.Start();
byte* src = (byte*)ptr;
byte* dest = (byte*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(byte); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time byte copy is {0} ms.", averageTime);
{
watch.Reset();
watch.Start();
int* src = (int*)ptr;
int* dest = (int*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(int); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time int copy is {0} ms.", averageTime);
{
watch.Reset();
watch.Start();
long* src = (long*)ptr;
long* dest = (long*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(long); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time long copy is {0} ms.", averageTime);
watch.Reset();
watch.Start();
{
copystruct2* src = (copystruct2*)ptr;
copystruct2* dest = (copystruct2*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(copystruct2); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time copystruct2 copy is {0} ms.", averageTime);
watch.Reset();
watch.Start();
{
copystruct4* src = (copystruct4*)ptr;
copystruct4* dest = (copystruct4*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(copystruct4); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time copystruct4 copy is {0} ms.", averageTime);
watch.Reset();
watch.Start();
{
copystruct16* src = (copystruct16*)ptr;
copystruct16* dest = (copystruct16*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(copystruct16); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time copystruct16 copy is {0} ms.", averageTime);
watch.Reset();
watch.Start();
{
copystruct128* src = (copystruct128*)ptr;
copystruct128* dest = (copystruct128*)ptr2;
for (int j = 0; j < count; j++)
{
for (int i = 0; i < size / sizeof(copystruct128); i++)
{
dest[i] = src[i];
}
}
watch.Stop();
averageTime = watch.ElapsedMilliseconds / (double)count;
}
Console.WriteLine("Average time copystruct128 copy is {0} ms.", averageTime);
Marshal.FreeHGlobal(ptr);
Marshal.FreeHGlobal(ptr2);
Console.ReadKey();
}
}
}
[/csharp]
コメント
今日は謎の宴会らしい...スーツが入るのかっ!?(GRB爆
「侍ジャパン」宮崎県入り 「プレミア12」向け きょうから合宿
【#総選挙】 衆議院選挙 きょう投票 ...ドロドロドロ(24/10/27)
【#線状降水帯】宮崎 延岡「土砂崩れで家がつぶれている」通報 1人不明(24/10/23)
【冬】お~日本海に筋雲が出ちょる!冬がキター
【#寒冷前線】13時頃30℃の気温が今は25℃無いぞー
【訃報】 俳優の西田敏行さん亡くなる 76歳 東京の自宅で
【#台風】衆議院議員選挙の投票日に超大型台風が直撃!なのか?(24/10/17)
【#キロタン】奄美地方(鹿児島県)記録的短時間大雨情報 第1号(24/10/16)
生駒高原へコスモスを見物しに行ってみた