【问题标题】:Optimize memcpy on Windows (MSVC++)优化 Windows 上的 memcpy (MSVC++)
【发布时间】:2020-08-24 13:55:47
【问题描述】:

假设我想复制#SIZE no。从一个数组到另一个数组的整数。我看到以下 3 个的性能是不同的,即使它们完成了相同的工作:

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(对于 100 万个整数的大小)。我知道在每种情况下使用寄存器的大小都会不同,但我期待 MSVC 编译器通过使用最高(向量)寄存器大小来优化所有这些。内存对齐可以通过创建剥离和剩余循环来实现。也有可能使用非临时/流媒体商店。有没有办法在编译器中强制进行这种优化?

另外,有没有办法在 MSVC 中强制内联 memcpy?

【问题讨论】:

  • 结果提示复制的尺寸越小,经过的时间越短。 memcpy() 的第二次和第三次调用不会做你想做的事情(复制 size 整数)。
  • memcpy 的第三个参数以字节为单位。这三个语句正在复制不同数量的内存。
  • 您在前两个参数中所做的所有这些转换都是多余的。 memcpy 采用 void 指针作为前两个参数,因此不需要强制转换。
  • 另外,在任何优秀的优化编译器中使用类型安全的std::copy 将或应该归结为memcpy。也许您应该使用它而不是在很多地方进行投射。
  • 谢谢大家。没有正确阅读文档并因假设而错过的愚蠢错误。我有一个测试来检查数组的端点是否完全复制但我发现我犯了一个错误并且正在检查错误的数组。

标签: c++ windows visual-c++ memcpy


【解决方案1】:

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

从 src 指向的对象复制 bytes 到 dest 指向的对象。两个对象都被重新解释为无符号字符数组。

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

【讨论】:

    【解决方案2】:

    即使他们完成相同的工作

    不,那不是真的。

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

    【讨论】:

      【解决方案3】:

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

      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微秒。 p>

      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 微秒

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-28
        • 2018-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-19
        相关资源
        最近更新 更多