【问题标题】:Fastest way to memset on modern amd64 CPUs在现代 amd64 CPU 上进行 memset 的最快方法
【发布时间】: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 之后已经存在)。

标签: assembly x86-64 memset


【解决方案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 中的原因之一)。

【讨论】:

    猜你喜欢
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2011-08-07
    • 2011-01-20
    • 1970-01-01
    相关资源
    最近更新 更多