在WindowsMSVC ++上优化memcpy

问题描述

假设我要复制#SIZE号。从一个数组到另一个数组的整数。我发现以下三种方法性能不同,即使它们完成相同的工作:

memcpy((char*)(arr),(char*)(temp),sizeof(int) * size);
memcpy((int*)(arr),(int*)(temp),size);
memcpy((double*)(arr),(double*)(temp),size/(sizeof(double)/sizeof(int)));

时间分别为160 us,40 us和20 us(大小为1百万个整数)。我知道每种情况下寄存器的使用大小都不同,但是我期望MSVC编译器通过使用最大(向量)寄存器大小来优化所有这些寄存器。内存对齐可以通过创建剥离循环和剩余循环来实现。也有可能使用非临时/流存储。有没有办法在编译器中强制执行此优化?

还可以在MSVC中强制内联memcpy吗?

解决方法

即使他们完成了相同的工作

不,那是不正确的。

memcpy的最后一个参数是长度,以字节为单位,而不是项目数。第二行的工作量减少了四倍,只复制了所需内容的四分之一(或者第一行复制了四倍)。

,

memcpy总是复制字节,而您似乎假定它复制了传递的类型(intdouble)。来自cppreference

从src指向的对象到dest指向的对象的

份计数 bytes 。这两个对象都重新解释为无符号字符数组。

由于您的三个调用确实复制了不同数量的字节,因此可以预期运行时会有所不同。如果sizeof(int) == 4double的大小是平台上int的两倍,则测量的时间是一致的。

,

其他答案很好地解释了这个问题,我只添加一些数字以供澄清:

memcpy((char*)(arr),(char*)(temp),sizeof(int) * size);

第一个呼叫复制了sizeof(int) * size个字节,很可能是 4 * size个字节 160微秒

memcpy((int*)(arr),(int*)(temp),size);

第二个呼叫复制了 size个字节,因此减少了4倍,并且也减少了4倍的时间,即160/4 = 40微秒

memcpy((double*)(arr),(double*)(temp),size/(sizeof(double)/sizeof(int)));

第三个呼叫复制了size/(sizeof(double)/sizeof(int))个字节,很可能是size/(8/4)个字节,因此是 size/2个字节。这分别比第一种和第二种情况少八倍和两倍。花费160/8 = 40/2 = 20微秒

因此,运行时与复制的字节数成正比。