我写了一个简单的代码,它将结构数组复制到C#中的另一个数组中。 .NET Core 2.0,控制台应用程序,64位可执行文件,发布模式,Windows 10,Intel i7 7700k。 通过在Visual Studio中断开并观察反汇编窗口来进行汇编。
struct MyStruct
{
public float F1;
public float F2;
public float F3;
public float F4;
}
class Program
{
private static MyStruct[] arr1 = new MyStruct[1024];
private static MyStruct[] arr2 = new MyStruct[1024];
static void Main(string[] args)
{
for (int i = 0; i < arr1.Length; i++)
arr1[i] = arr2[i];
}
}
我期待汇编中的这段代码将src内存复制到寄存器然后复制到目标数组。
在汇编中,我看到以下内容(省略循环样板):
00007FFB33C704DC vmovdqu xmm0,xmmword ptr [rdx]
00007FFB33C704E1 vmovdqu xmmword ptr [rsp+30h],xmm0
00007FFB33C704E8 cmp esi,dword ptr [rax+8]
00007FFB33C704EB jae 00007FFB33C7051E
00007FFB33C704ED lea rax,[rax+rcx+10h]
00007FFB33C704F2 vmovdqu xmm0,xmmword ptr [rsp+30h]
00007FFB33C704F9 vmovdqu xmmword ptr [rax],xmm0
它将每个结构复制到堆栈,然后才从堆栈复制到目标数组。
如果我将结构大小从128位减少到64位,一切都会变好:
00007FFB33C804D8 vmovss xmm0,dword ptr [rdx]
00007FFB33C804DD vmovss xmm1,dword ptr [rdx+4]
00007FFB33C804E3 cmp esi,dword ptr [rax+8]
00007FFB33C804E6 jae 00007FFB33C80518
00007FFB33C804E8 lea rax,[rax+rcx*8+10h]
00007FFB33C804ED vmovss dword ptr [rax],xmm0
00007FFB33C804F2 vmovss dword ptr [rax+4],xmm1
为什么不使用堆栈就能复制128位结构?