我需要简单的带 SSE 的 ZeroMemory 实现(首选 SSE2)有人可以帮忙吗?我正在通过 SO 和网络搜索,但没有找到直接的答案。
问问题
2073 次
3 回答
4
是不够好ZeroMemory()
还是memset()
不够好?
免责声明:以下部分可能是 SSE3。
- 通过循环填充任何未对齐的前导字节,直到地址是 16 的倍数
push
保存一个 xmm regpxor
将 xmm reg 归零- 而剩余长度 >= 16,
movdqa
或者movntdq
写
pop
恢复 xmm reg。- 填充任何未对齐的尾随字节。
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 回答