问题描述
我试图用rep movsb
指令创建我的memcpy代码。禁用优化后,它可以与任何大小完美配合。但是,当我启用优化后,它无法按预期运行。
问题
创建我自己的memcpy的动机:
我从Intel® 64 and IA-32 Architectures Optimization Reference Manual 第3.7.6节中了解了用于memcpy的增强型movsb。我来到了libc源代码,我看到来自libc的默认memcpy使用SSE而不是movsb
。
因此,我想比较Memcpy的 SSE指令和 rep movsb 的性能。但是现在,我发现它有问题。
用于重现问题的简单代码(test.c)
#include <stdio.h>
#include <string.h>
inline static void *my_memcpy(
register void *dest,register const void *src,register size_t n
) {
__asm__ volatile(
"mov %0,%%rdi;"
"mov %1,%%rsi;"
"mov %2,%%rcx;"
"rep movsb;"
:
: "r"(dest),"r"(src),"r"(n)
: "rdi","rsi","rcx"
);
return dest;
}
#define to_boolean_str(A) ((A) ? "true" : "false")
int main()
{
char src[32];
char dst[32];
memset(src,'a',32);
memset(dst,'b',32);
my_memcpy(dst,src,1);
printf("%s\n",to_boolean_str(!memcmp(dst,1)));
my_memcpy(dst,2);
printf("%s\n",2)));
my_memcpy(dst,3);
printf("%s\n",3)));
return 0;
}
编译并运行
ammarfaizi2@integral:~$ gcc --version
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0
copyright (C) 2019 Free Software Foundation,Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or fitness FOR A PARTIculaR PURPOSE.
ammarfaizi2@integral:~$ gcc -O0 test.c -o test && ./test
true
true
true
ammarfaizi2@integral:~$ gcc -O1 test.c -o test && ./test
false
true
true
ammarfaizi2@integral:~$ gcc -O2 test.c -o test && ./test
false
true
true
ammarfaizi2@integral:~$ gcc -O3 test.c -o test && ./test
false
true
true
ammarfaizi2@integral:~$
摘要
如果启用了优化,则解决方法
按照书面规定,您的asm约束并不反映asm语句可以修改内存,因此编译器可以针对在dest
或src
上读取或写入内存的操作自由地对其进行重新排序。您需要将"memory"
添加到清单列表中。
正如其他人所述,您还应该编辑约束以避免mov
。如果这样做的话,您还需要在约束条件中表示事实,即asm现在修改了其参数(例如,使它们成为双重输入/输出)并备份了dest
的值,以便您可以返回它。因此,您可能会跳过此改进,直到您开始进行改进并了解约束的工作原理为止。