37

memcmp(a, b, size)よりもはるかに高速な理由:

for(i = 0; i < nelements; i++) {
    if a[i] != b[i] return 0;
}
return 1;

memcmp は CPU 命令か何かですか? memcmpオーバーザループを使用して大幅な高速化を実現したため、かなり深いに違いありません。

4

3 に答える 3

48

memcmp多くの場合、多くのアーキテクチャ固有の機能を利用するためにアセンブリで実装されます。これにより、C の単純なループよりもはるかに高速になります。

「ビルトイン」として

GCC はmemcmp(他の多くの機能と同様に) builtinsとしてサポートしています。GCC の一部のバージョン / 構成では、 への呼び出しmemcmpは として認識され__builtin_memcmpます。callライブラリ関数に aを発行する代わりにmemcmp、GCC は関数の最適化されたインライン バージョンとして機能するいくつかの命令を発行します。

cmpsbx86 では、これは、あるメモリ位置のバイト文字列を別のメモリ位置と比較する命令の使用を活用します。これはrepeプレフィックスと結合されているため、文字列は等しくなくなるまで、またはカウントが尽きるまで比較されます。(正確には何をしますかmemcmp)。

次のコードがあるとします。

int test(const void* s1, const void* s2, int count)
{
    return memcmp(s1, s2, count) == 0;
}

gcc version 3.4.4Cygwin では、次のアセンブリが生成されます。

; (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 用のバージョンがあります。

クールな部分は、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)

Linux カーネル内

memcmpLinux にはx86_64 用に最適化されたバージョンがないようですがmemcpyarch/x86/lib/memcpy_64.S. は、実行時に使用するバージョンを決定するだけでなく、起動時に一度だけこの決定を行うように実際にパッチを適用するために、代替インフラストラクチャ ( ) を使用することに注意してください。arch/x86/kernel/alternative.c

于 2014-01-14T05:43:45.763 に答える
0

memcmp は CPU 命令か何かですか?

これは、少なくとも非常に高度に最適化されたコンパイラ提供の組み込み関数です。プラットフォームに応じて、指定していない 1 つまたは 2 つのマシン命令の可能性があります。

于 2014-01-14T05:44:24.780 に答える
0

これは通常、メモリ ブロックを比較するための特殊な命令を使用して高速アセンブリに変換されるコンパイラ組み込み関数です。

組み込み memcmp

于 2014-01-14T05:45:49.283 に答える