【发布时间】:2015-11-29 13:53:53
【问题描述】:
我的程序在下面,我想用它来计算一个字符串的长度。
.CODE
EQUAL_EACH = 1000b
strlen_sse PROC
string equ [esp+4]
mov ecx, string
;ecx = string
mov eax, -16
mov edx, ecx
pxor xmm0, xmm0
STRLEN_LOOP:
add eax, 16
PcmpIstrI xmm0, xmmword ptr [edx+eax], EQUAL_EACH
jnz STRLEN_LOOP
add eax, ecx
ret
strlen_sse ENDP
END
main 如下所示:
#include<stdio.h>
#include<windows.h>
extern "C" int strlen_sse(const char* src);
int main(){
DWORD start,stop;
char* str = "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf";
start = GetTickCount();
for (; i < 100000000; i++) {
strlen_sse(str);
}
stop = GetTickCount();
printf("%lld ms\n",stop-start);
}
我的工作环境是visual studio 2015 community,项目的平台是x64(active),编译时没有任何错误。
我该如何修复这个错误?
【问题讨论】:
-
你是否检查过你传入的字符串的对齐方式?
-
当我更改
str以满足对齐时,错误仍然存在,我将其更改为"asdfasdfasdfasd",长度为16个字节。 -
但它是否在 16 个字节上对齐(即字符串地址的 4 个最低有效位全为零)?
-
如果你写了汇编代码,但你不能让它工作,那么你需要切换到C或一些更高级别的代码。另一种选择是坚持;查找您有哪些调试工具,从英特尔网站下载说明手册等。
-
这看起来很慢(因为 SSE4.2 字符串指令仍然不快,在引入了几代之后)。也许可以尝试使用归零寄存器的
pcmpeqb,以及PTEST / jcc或pmovmsk / test/jcc。PcmpIstrI是 4 uops with a memory operand, with a throughput of one per 3 cycles,在 Intel Haswell 上。