FastMemcpy icon indicating copy to clipboard operation
FastMemcpy copied to clipboard

一些小小的问题

Open lhmouse opened this issue 8 years ago • 4 comments

和现在的 MCFCRT 比较了一下,因为 MCFCRT 不打算支持 AVX 就只测试了 SSE 的(实际上是懒得改,其实比较简单,目前的复制操作都是两个连续 movups 打包的,这地方改改就能支持 AVX):

4311

https://github.com/lhmouse/MCF/blob/master/MCFCRT/src/stdc/string/_memcpy_impl.h#L292

gcc (gcc-7-branch HEAD with MCF thread model, built by LH_Mouse.) 7.3.1 20180125
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

处理器是 Intel Xeon E3 1230v3 ,Haswell 架构。

你这个测试我看了下,有几个小问题:

  1. #1 里面提过的。这个二次函数调用的开销对 32 字节的复制测试的影响比较大,大概有十几个毫秒。
  2. 只有 32 64 512 等尺寸的复制,没有带余数的。
  3. timeGetTime() 太不精确了(误差经常在十几个毫秒),建议用 QuertPerformanceCounter(), 还不用链接 winmm

实现的问题也有一些:

  1. 全部用 static 函数涉嫌利用编译器对 internal linkage 的函数的 aggressive optimization 造假。(逃)
  2. memcpy_fast() 最后的 memcpy_tiny() 实际上没有必要:因为上面 if (size <= 128) { 条件不成立的缘故,直接用 _mm_storeu_si128() 处理最后的 xmmword 就行。
  3. prefetching 实测意义不大。
  4. 不建议用整数的 sse 指令。它要求 SSE2,指令长度更大所以 cache locality 不好。相比之下, _mm_{loadu,load,storeu,store,stream}_ps() 仅要求 SSE 支持,并且指令长度更小。(由于 Core2 上存在延迟问题, GCC 会将 movups 优化为 movlpsmovhps 的拼合。然而这是后话,Haswell 上已经没有这延迟问题了。)

lhmouse avatar Jan 27 '18 16:01 lhmouse

呵呵,现在这些 crt 也进步不小啊,

  1. memcpy_tiny 最终应是按照 inline 进 memcpy_fast 中的,你可以试试 -O3 选项,如果 -O2 的话,很多地方没法优化。
  2. timeGetTime 只是测试个大概,QFP 写起来代码更长,懒得写了,因为本身循环数较多,误差也是毫秒级别的。
  3. static 问题,你可以改做函数指针,实测还是比 memcpy 快。
  4. 针对你说的最后一次 memcpy_tiny 可以避免的问题,这是避免不了的,因为中间块拷贝部分,步常是128字节,也就是说最多可能剩下 127 个字节来,你的 _mm_storeu_si128() 一次只能拷贝16个字节,你要展开写,它也还是一次 memcpy_tiny。
  5. prefetching 根据机器不同,至少一半机器上的确有效果的。
  6. movups 问题,有空可以试试。
  7. 至于尺寸,我另外一个版本的代码里测试过不对齐的尺寸,测试结果类似,篇幅问题,我把那些测试删除了,有兴趣你可以加上去。

skywind3000 avatar Jan 27 '18 19:01 skywind3000

  1. -O3-O2 慢。
  2. 你不是封装成函数了么,应该不差太多。返回的时间建议用 double 不建议用 unsigned
  3. 不评论。
  4. 不会把指针退一个字节变成不对齐的再复制? 567 同 3。

lhmouse avatar Jan 27 '18 19:01 lhmouse

QFP长也是醉了.c.jpg 还有都Haswell了还纠结这点指令长度嘛……?

FrankHB avatar Jan 28 '18 03:01 FrankHB

QFP长也是醉了.c.jpg 还有都Haswell了还纠结这点指令长度嘛……?

不过,实际测下来的速度 movupd > movups = lddqu ,虽然 movupd 是 SSE2 而且比 movups 好多一个 operand size override prefix 。

lhmouse avatar Jan 28 '18 04:01 lhmouse