C#(Mono)托管与非托管阵列:基准偏好托管?
令人惊讶的是,对以下各项进行基准测试可以为受管阵列提供更好的结果(速度快10%,一致性好)。我在Unity中测试,所以可能与Mono有关C#(Mono)托管与非托管阵列:基准偏好托管?,c#,arrays,mono,benchmarking,unsafe,C#,Arrays,Mono,Benchmarking,Unsafe,令人惊讶的是,对以下各项进行基准测试可以为受管阵列提供更好的结果(速度快10%,一致性好)。我在Unity中测试,所以可能与Mono有关 unsafe void Bench() { //Locals int i, j; const int bufSize = 1024 * 1024; const int numIterations = 1000; const float gain = 1.6745f;
unsafe void Bench()
{
//Locals
int i, j;
const int bufSize = 1024 * 1024;
const int numIterations = 1000;
const float gain = 1.6745f;
float[] managedBuffer;
IntPtr ptr;
float * unmanagedBuffer;
Stopwatch stopwatch;
// Allocations
managedBuffer = new float[ bufSize ];
for( i = 0; i < bufSize; i++ )
{
managedBuffer[ i ] = UnityEngine.Random.value;
}
ptr = Marshal.AllocHGlobal( bufSize * sizeof( float ) );
unmanagedBuffer = ( float * )ptr.ToPointer();
Marshal.Copy( managedBuffer, 0, ptr, bufSize );
stopwatch = new Stopwatch();
stopwatch.Start();
// Unmanaged array iterations
for( i = 0; i < numIterations; i++ )
{
for( j = 0; j < bufSize; j++ )
{
unmanagedBuffer[ j ] *= gain;
}
}
UnityEngine.Debug.Log( stopwatch.ElapsedMilliseconds );
stopwatch.Reset();
stopwatch.Start();
// Managed array iterations
for( i = 0; i < numIterations; i++ )
{
for( j = 0; j < bufSize; j++ )
{
managedBuffer[ j ] *= gain;
}
}
UnityEngine.Debug.Log( stopwatch.ElapsedMilliseconds );
Marshal.FreeHGlobal( ptr );
}
unsafe void Bench()
{
//当地人
int i,j;
常量int bufSize=1024*1024;
常数整数=1000;
常数浮点增益=1.6745f;
浮动[]管理缓冲区;
IntPtr-ptr;
浮动*非托管缓冲区;
秒表;
//分配
managedBuffer=newfloat[bufSize];
对于(i=0;i
我正在为一个性能非常关键的音频应用程序试验不安全的代码。我希望提高性能,减少/消除垃圾收集
任何见解,谢谢 不是一个真正的答案,但需要更多的空间而不是评论 如果您使用来观察IL代码,则区别在于(版本、默认设置、我的电脑:Windows 7 64): 我不知道每个IL指令对应多少机器代码,但这可能是优化问题(请参阅非托管缓冲区情况下计算索引所需的工作量)
我注意到迭代次数和时间之间的非线性关系: 第一列是
numIterations
,第二列是未更改时间(ms),最后一列是管理时间(ms)
直到
170
它是线性的,然后开始发生一些事情(忽略增量,屏幕上是10
,我试过5
它也很好,直到170
)。这让我很烦,我真的很想在这里得到真正的答案。不是答案,但我需要空间。
使用C#nad VS13,我看到了不同的乘法汇编
非托管的
00007FFC013555D9 movsxd rcx,dword ptr [rbp+0D8h]
00007FFC013555E0 mov rax,qword ptr [rbp+0C0h]
00007FFC013555E7 lea rax,[rax+rcx*4]
00007FFC013555EB mov qword ptr [rbp+50h],rax
00007FFC013555EF mov rax,qword ptr [rbp+50h]
00007FFC013555F3 movss xmm0,dword ptr [7FFC013558A0h]
00007FFC013555FB mulss xmm0,dword ptr [rax]
00007FFC013555FF mov rax,qword ptr [rbp+50h]
00007FFC01355603 movss dword ptr [rax],xmm0
00007FFC01355722 movsxd rcx,dword ptr [rbp+0D8h]
00007FFC01355729 mov rax,qword ptr [rbp+0D0h]
00007FFC01355730 mov rax,qword ptr [rax+8]
00007FFC01355734 mov qword ptr [rbp+78h],rcx
00007FFC01355738 cmp qword ptr [rbp+78h],rax
00007FFC0135573C jae 00007FFC01355748
00007FFC0135573E mov rax,qword ptr [rbp+78h]
00007FFC01355742 mov qword ptr [rbp+78h],rax
00007FFC01355746 jmp 00007FFC0135574D
00007FFC01355748 call 00007FFC60E86590
00007FFC0135574D mov rcx,qword ptr [rbp+0D0h]
00007FFC01355754 mov rax,qword ptr [rbp+78h]
00007FFC01355758 lea rax,[rcx+rax*4+10h]
00007FFC0135575D mov qword ptr [rbp+80h],rax
00007FFC01355764 mov rax,qword ptr [rbp+80h]
00007FFC0135576B movss xmm0,dword ptr [7FFC013558A0h]
00007FFC01355773 mulss xmm0,dword ptr [rax]
00007FFC01355777 mov rax,qword ptr [rbp+80h]
00007FFC0135577E movss dword ptr [rax],xmm0
管理的
00007FFC013555D9 movsxd rcx,dword ptr [rbp+0D8h]
00007FFC013555E0 mov rax,qword ptr [rbp+0C0h]
00007FFC013555E7 lea rax,[rax+rcx*4]
00007FFC013555EB mov qword ptr [rbp+50h],rax
00007FFC013555EF mov rax,qword ptr [rbp+50h]
00007FFC013555F3 movss xmm0,dword ptr [7FFC013558A0h]
00007FFC013555FB mulss xmm0,dword ptr [rax]
00007FFC013555FF mov rax,qword ptr [rbp+50h]
00007FFC01355603 movss dword ptr [rax],xmm0
00007FFC01355722 movsxd rcx,dword ptr [rbp+0D8h]
00007FFC01355729 mov rax,qword ptr [rbp+0D0h]
00007FFC01355730 mov rax,qword ptr [rax+8]
00007FFC01355734 mov qword ptr [rbp+78h],rcx
00007FFC01355738 cmp qword ptr [rbp+78h],rax
00007FFC0135573C jae 00007FFC01355748
00007FFC0135573E mov rax,qword ptr [rbp+78h]
00007FFC01355742 mov qword ptr [rbp+78h],rax
00007FFC01355746 jmp 00007FFC0135574D
00007FFC01355748 call 00007FFC60E86590
00007FFC0135574D mov rcx,qword ptr [rbp+0D0h]
00007FFC01355754 mov rax,qword ptr [rbp+78h]
00007FFC01355758 lea rax,[rcx+rax*4+10h]
00007FFC0135575D mov qword ptr [rbp+80h],rax
00007FFC01355764 mov rax,qword ptr [rbp+80h]
00007FFC0135576B movss xmm0,dword ptr [7FFC013558A0h]
00007FFC01355773 mulss xmm0,dword ptr [rax]
00007FFC01355777 mov rax,qword ptr [rbp+80h]
00007FFC0135577E movss dword ptr [rax],xmm0
显然,代码越大,执行速度越慢 在对非托管数组进行迭代时,只是尝试了指针算术而不是索引器,情况更糟……基准测试是一门棘手的艺术,容易出错,机器代码中的微小差异也很明显。小于15%的差异不具有统计相关性。至少调用此代码10次,减少数量,这样您就不必等待太久。注意结果中的显著变化。当我在.NET上尝试时,代码以相同的速度运行。应该如此。