Memory 内在memcmp
根据本文,memcmp不是GCC的固有功能。如果您想在gcc下加速glibc的memcmp,则需要使用文档中定义的较低级别的内部函数。然而,当在互联网上搜索时,似乎许多人都认为memcmp是一个内置功能。它是针对某些编译器的,而不是针对其他编译器的吗?您的链接似乎是针对x86体系结构特定的内置函数的,根据memcmp,它是由gcc作为独立于体系结构的内置函数实现的 编辑: 使用i686,-O2的Cygwin gcc版本3.3.1编译以下代码:Memory 内在memcmp,memory,gcc,intrinsics,Memory,Gcc,Intrinsics,根据本文,memcmp不是GCC的固有功能。如果您想在gcc下加速glibc的memcmp,则需要使用文档中定义的较低级别的内部函数。然而,当在互联网上搜索时,似乎许多人都认为memcmp是一个内置功能。它是针对某些编译器的,而不是针对其他编译器的吗?您的链接似乎是针对x86体系结构特定的内置函数的,根据memcmp,它是由gcc作为独立于体系结构的内置函数实现的 编辑: 使用i686,-O2的Cygwin gcc版本3.3.1编译以下代码: #include <stdlib.h>
#include <stdlib.h>
struct foo {
int a;
int b;
} ;
int func(struct foo *x, struct foo *y)
{
return memcmp(x, y, sizeof (struct foo));
}
请注意,repzcmpsb例程可能不会比glibc的memcmp快。事实上,在我的测试中,它从来没有更快过,即使只是比较几个字节
参见2017年,GCC和Clang似乎对大小为1、2、4、8的缓冲区和其他一些缓冲区进行了一些优化,例如3、5和8的倍数。。知道这些是否以特定于体系结构的方式进行了优化吗?是的。这样做有一个特定的SIMD内在集(如果我没记错的话,在SSE4.2中)。为什么不使用一个2字的
repz cmpsl
?或者更好,如果(x->a==y->a&&x->b==y->b)?gcc太差劲了…也请查看glibc的memcmp。GCC和glibc之间的关系相当复杂,两者都提供相同函数的不同版本,有时在头文件中进行斗争,头文件的定义实际上会在用户程序中使用。+1是一个很好的链接!我自己也在寻找答案,为什么libc memcmp()比简单的repz cmpsb
执行速度快几个数量级。我猜这与对齐有关,现在我知道了:)真的,在4.8上memcmp
用-O3
编译成jmp memcmp
,而不是直接组装。谁能总结一下glibc如何更快?“与对齐有关吗?”CiroSantilli六四事件法轮功包卓轩 典型的“fastmemcmp
”会逐字节比较,直到达到对齐边界,然后逐字比较(通常是本机字大小,x86-64上为64位),如果剩余的字节数小于字大小,则会逐字节比较,直到完成。快速检查小尺寸的特殊情况代码也很常见。请参见glibc的source:
0: 55 push %ebp
1: b9 08 00 00 00 mov $0x8,%ecx
6: 89 e5 mov %esp,%ebp
8: fc cld
9: 83 ec 08 sub $0x8,%esp
c: 89 34 24 mov %esi,(%esp)
f: 8b 75 08 mov 0x8(%ebp),%esi
12: 89 7c 24 04 mov %edi,0x4(%esp)
16: 8b 7d 0c mov 0xc(%ebp),%edi
19: f3 a6 repz cmpsb %es:(%edi),%ds:(%esi)
1b: 0f 92 c0 setb %al
1e: 8b 34 24 mov (%esp),%esi
21: 8b 7c 24 04 mov 0x4(%esp),%edi
25: 0f 97 c2 seta %dl
28: 89 ec mov %ebp,%esp
2a: 5d pop %ebp
2b: 28 c2 sub %al,%dl
2d: 0f be c2 movsbl %dl,%eax
30: c3 ret
31: 90 nop