在现代 amd64 CPU 上进行 memset 的最快方法

Posted

技术标签:

【中文标题】在现代 amd64 CPU 上进行 memset 的最快方法【英文标题】:Fastest way to memset on modern amd64 CPUs 【发布时间】:2014-03-12 20:40:02 【问题描述】:

我想在 amd64 程序集中用零填充一个 4096 字节数组(与 4096 字节边界对齐)。我正在寻找便携式和单 CPU 类型的解决方案。

我知道rep stosq 可以解决问题,但是有更快的方法吗? MMX?上证所?它快多少?在一条指令中可以将多少字节写入内存(没有rep)?我们可以假设内存缓存是空的。我不需要一个完整的功能实现,我只需要具有关键汇编指令的基本思想。

我刚刚看到movdqa 指令一次可以写入16 个字节。是不是每条 8 字节的 2 条 mov 指令快两倍?

【问题讨论】:

如果您知道它已超出缓存,则可能值得尝试流媒体存储。 @Mysticial:流媒体存储一次可以写入超过 8 个字节吗? 获取规范零页面的 COW 副本? @pts 远不止这些。如果您受内存限制,则您会受到内存带宽的限制。今天一个典型的桌面只能获得大约 5 字节/周期。所以不管指令有多宽,你的记忆都会阻碍你。流媒体部分通常会有所帮助,因为它消除了一些来回。 (例如,如果要覆盖所有缓存行,则无需读取缓存行。) @KerrekSB 虽然您的建议很好,但说如何做到这一点也很有帮助。诀窍是使用buf = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON /* | MAP_LOCKED */, -1, 0);(如果您运行的是特权,MAP_LOCKED 将保证页面在mmap 之后已经存在)。 【参考方案1】:

您的问题的答案可以通过查看 Agner Fog 的 asmlib 中的文件 memset64.asm 中的源代码来找到。

他的代码有 AVX 和 SSE 的版本。据我所知,代码对小于MemsetCacheLimit 的数组大小执行_mm256_store_ps (vmovaps)。对于更大的数组大小,他使用_mm256_stream_ps (vmovntps) 进行非临时存储。还有其他几个因素会影响结果。查看代码。对于大多数使用内部函数的 C/C++ 情况,您可能会获得相同的性能。

请注意,GCC 中的内置 memset 函数以及我上次检查的 glibc 中的版本都是 not optimized(这是 memset 在 asmlib 中的原因之一)。

【讨论】:

以上是关于在现代 amd64 CPU 上进行 memset 的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在现代 GPU 上进行老式 2d 位图?

在 64 位 Ubuntu 14.04 中使用 Nvidia *和* AMD GPU 进行 OpenCL 开发

e1-2500cpu是64位的吗?

X86 X64 X86_64 AMD64 区别

目前CPU分类

x86 x64 x86_64 AMD64 区别