Closed. This question needs details or clarity. It is not currently accepting answers. Learn more。
想改进这个问题吗添加细节并通过editing this post澄清问题。
三年前关闭。
我已经实现了一个SSE4.2版本的memcpy,但在XeonV3上,我似乎无法击败intel fast memcpy我在收集例程中使用我的例程,其中每个位置的数据在4到15字节之间变化我在这里和英特尔网站上看了很多帖子,但都不走运什么是一个好的来源,我应该看看?
重叠存储是有效的(L1缓存可以很好地吸收它们),现代cpu应该能够很好地处理这一点未对齐的货物/商店足够便宜,我认为你打不过这个(假设页面分割加载的平均数量即使缓存线拆分负载超过平均数量,也可能不会有问题。)
这意味着在内部循环中没有条件分支来决定复制策略或任何掩码生成或任何其他操作您只需要在收集缓冲区的末尾多加一个12B或其他东西,以防最后一个副本应该是4B(您还需要收集的元素不在页面末尾16B的范围内,其中下一页未映射或不可读)
如果读取超过所收集元素的末尾是一个问题,那么负载的
我使用
回复:您的意见:不要使用传统的SSE
AVX版本(
相关报道:我不久前发布了一个关于using
电影马赛克在很大程度上是一种“当时看来是个好主意”的东西我从来没用过——斯蒂芬·卡农
想改进这个问题吗添加细节并通过editing this post澄清问题。
三年前关闭。
我已经实现了一个SSE4.2版本的memcpy,但在XeonV3上,我似乎无法击败intel fast memcpy我在收集例程中使用我的例程,其中每个位置的数据在4到15字节之间变化我在这里和英特尔网站上看了很多帖子,但都不走运什么是一个好的来源,我应该看看?
最佳答案
你能用16B的负载和存储来进行收集,然后在最后重叠多少垃圾字节吗?
// pseudocode: pretend these intrinsics take void* args, not float
char *dst = something;
__m128 tmp = _mm_loadu_ps(src1);
_mm_storeu_ps(dst, tmp);
dst += src1_size;
tmp = _mm_loadu_ps(src2);
_mm_storeu_ps(dst, tmp);
dst += src2_size;
...
重叠存储是有效的(L1缓存可以很好地吸收它们),现代cpu应该能够很好地处理这一点未对齐的货物/商店足够便宜,我认为你打不过这个(假设页面分割加载的平均数量即使缓存线拆分负载超过平均数量,也可能不会有问题。)
这意味着在内部循环中没有条件分支来决定复制策略或任何掩码生成或任何其他操作您只需要在收集缓冲区的末尾多加一个12B或其他东西,以防最后一个副本应该是4B(您还需要收集的元素不在页面末尾16B的范围内,其中下一页未映射或不可读)
如果读取超过所收集元素的末尾是一个问题,那么负载的
vpmaskmov
可能实际上是一个好主意如果您的元素是4B对齐的,那么读取超过结尾的3个字节总是可以的您仍然可以使用正常的16B矢量存储到dst缓冲区中。我使用
_ps
加载是因为movups
比movupd
或movdqu
短1个字节,但执行相同的操作(请参见Agner Fog's microarch pdf标记wiki中的x86和其他链接)(clang有时甚至会为movaps
使用movups
/_mm_store_si128
。)回复:您的意见:不要使用传统的SSE
maskmovdqu
最大的问题是它只起到存储的作用,所以它不能帮助你避免在收集的对象之外阅读It's slow,它会绕过缓存(这是一个NT存储),因此在重新加载此数据时速度会非常慢。AVX版本(
vmaskmov
和vpmaskmov
)与此不同,因此将代码转换为使用maskmovdqu
可能会大大降低速度。相关报道:我不久前发布了一个关于using
vmovmaskps
for the end of unaligned buffers的问答我得到了一些有趣的回答显然,这通常不是解决任何问题的最佳方法,尽管我(聪明的IMO)生成一个面具的策略非常有效。电影马赛克在很大程度上是一种“当时看来是个好主意”的东西我从来没用过——斯蒂芬·卡农
关于c - 击败_intel_fast_memcpy的矢量化memcpy? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39153868/
10-11 15:41