memcmp(a, b, size)
よりもはるかに高速な理由:
for(i = 0; i < nelements; i++) {
if a[i] != b[i] return 0;
}
return 1;
memcmp は CPU 命令か何かですか? memcmp
オーバーザループを使用して大幅な高速化を実現したため、かなり深いに違いありません。
memcmp(a, b, size)
よりもはるかに高速な理由:
for(i = 0; i < nelements; i++) {
if a[i] != b[i] return 0;
}
return 1;
memcmp は CPU 命令か何かですか? memcmp
オーバーザループを使用して大幅な高速化を実現したため、かなり深いに違いありません。
memcmp
多くの場合、多くのアーキテクチャ固有の機能を利用するためにアセンブリで実装されます。これにより、C の単純なループよりもはるかに高速になります。
GCC はmemcmp
(他の多くの機能と同様に) builtinsとしてサポートしています。GCC の一部のバージョン / 構成では、 への呼び出しmemcmp
は として認識され__builtin_memcmp
ます。call
ライブラリ関数に aを発行する代わりにmemcmp
、GCC は関数の最適化されたインライン バージョンとして機能するいくつかの命令を発行します。
cmpsb
x86 では、これは、あるメモリ位置のバイト文字列を別のメモリ位置と比較する命令の使用を活用します。これはrepe
プレフィックスと結合されているため、文字列は等しくなくなるまで、またはカウントが尽きるまで比較されます。(正確には何をしますかmemcmp
)。
次のコードがあるとします。
int test(const void* s1, const void* s2, int count)
{
return memcmp(s1, s2, count) == 0;
}
gcc version 3.4.4
Cygwin では、次のアセンブリが生成されます。
; (prologue)
mov esi, [ebp+arg_0] ; Move first pointer to esi
mov edi, [ebp+arg_4] ; Move second pointer to edi
mov ecx, [ebp+arg_8] ; Move length to ecx
cld ; Clear DF, the direction flag, so comparisons happen
; at increasing addresses
cmp ecx, ecx ; Special case: If length parameter to memcmp is
; zero, don't compare any bytes.
repe cmpsb ; Compare bytes at DS:ESI and ES:EDI, setting flags
; Repeat this while equal ZF is set
setz al ; Set al (return value) to 1 if ZF is still set
; (all bytes were equal).
; (epilogue)
参照:
の高度に最適化されたバージョンはmemcmp
、多くの C 標準ライブラリに存在します。これらは通常、アーキテクチャ固有の命令を利用して、大量のデータを並行して処理します。
Glibc には、次の命令セット拡張を利用できるmemcmp
x86_64 用のバージョンがあります。
sysdeps/x86_64/memcmp.S
sysdeps/x86_64/multiarch/memcmp-sse4.S
sysdeps/x86_64/multiarch/memcmp-ssse3.S
クールな部分は、glibc が (実行時に) CPU が持つ最新の命令セットを検出し、それに最適化されたバージョンを実行することです。からのこのスニペットを参照してくださいsysdeps/x86_64/multiarch/memcmp.S
:
ENTRY(memcmp)
.type memcmp, @gnu_indirect_function
LOAD_RTLD_GLOBAL_RO_RDX
HAS_CPU_FEATURE (SSSE3)
jnz 2f
leaq __memcmp_sse2(%rip), %rax
ret
2: HAS_CPU_FEATURE (SSE4_1)
jz 3f
leaq __memcmp_sse4_1(%rip), %rax
ret
3: leaq __memcmp_ssse3(%rip), %rax
ret
END(memcmp)
memcmp
Linux にはx86_64 用に最適化されたバージョンがないようですがmemcpy
、arch/x86/lib/memcpy_64.S
. は、実行時に使用するバージョンを決定するだけでなく、起動時に一度だけこの決定を行うように実際にパッチを適用するために、代替インフラストラクチャ ( ) を使用することに注意してください。arch/x86/kernel/alternative.c
memcmp は CPU 命令か何かですか?
これは、少なくとも非常に高度に最適化されたコンパイラ提供の組み込み関数です。プラットフォームに応じて、指定していない 1 つまたは 2 つのマシン命令の可能性があります。
これは通常、メモリ ブロックを比較するための特殊な命令を使用して高速アセンブリに変換されるコンパイラ組み込み関数です。