2

我需要简单的带 SSE 的 ZeroMemory 实现(首选 SSE2)有人可以帮忙吗?我正在通过 SO 和网络搜索,但没有找到直接的答案。

4

3 回答 3

4

是不够好ZeroMemory()还是memset()不够好?

免责声明:以下部分可能是 SSE3。

  1. 通过循环填充任何未对齐的前导字节,直到地址是 16 的倍数
  2. push保存一个 xmm reg
  3. pxor将 xmm reg 归零
  4. 而剩余长度 >= 16,
    1. movdqa或者movntdq
  5. pop恢复 xmm reg。
  6. 填充任何未对齐的尾随字节。

movntdq可能看起来更快,因为它告诉处理器不要将数据带入缓存,但是如果要使用数据,这可能会导致稍后的性能损失。如果您在释放内存之前清理它可能更合适(就像您可能使用的那样SecureZeroMemory())。

于 2012-10-08T18:15:25.747 回答
1

我想加快代码速度,而不是必须准确了解 CPU 的工作原理以及瓶颈在哪里。

在这里,您是我的速度优化例程,只是为了展示应该如何制作。

在我的电脑上比你的快 5 倍(清除 1MBytes 内存块),测试它并询问是否有人不清楚:

//edx = memory pointer must be 16 bytes aligned
//ecx = memory count must be multiple of 16 
    xorps       xmm0, xmm0                      //Clear xmm0
    mov         eax, ecx                        //Save ecx to eax
    and         ecx, 0FFFFFF80h                 //Clear only 128 byte pages
    jz          @ClearRest                      //Less than 128 bytes to clear
@Aligned128BMove:
    movdqa      [edx], xmm0                     //Clear first 16 bytes of 128 bytes 
    movdqa      [edx + 10h], xmm0               //Clear second 16 bytes of 128 bytes 
    movdqa      [edx + 20h], xmm0               //...
    movdqa      [edx + 30h], xmm0
    movdqa      [edx + 40h], xmm0
    movdqa      [edx + 50h], xmm0
    movdqa      [edx + 60h], xmm0
    movdqa      [edx + 70h], xmm0
    add         edx, 128                        //inc mem pointer
    sub         ecx, 128                        //dec counter
    jnz         @Aligned128BMove
@ClearRest:
    and         eax, 07Fh                       //Clear the rest
    jz          @Exit
@LoopRest:
    movdqa      [edx], xmm0
    add         edx, 16
    sub         eax, 16
    jnz         @LoopRest
@Exit:
于 2012-10-09T08:52:12.033 回答
0

CPU 中几乎所有的晶体管都用于以某种方式尽可能快地访问内存。CPU 已经在所有内存访问方面做得非常出色,并且指令的运行速度比可能的内存访问快得多。

因此,在大多数情况下,试图击败 memset 几乎是徒劳的,因为它已经受到您的记忆速度的限制(正如其他人所提到的)。

于 2012-10-12T00:49:10.300 回答