programing

memcmp가 루프 체크보다 훨씬 빠른 이유는 무엇입니까?

cafebook 2023. 11. 4. 13:17
반응형

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(또한 1톤의 다른 기능도 포함) 내장된 기능입니다.GCC의 일부 버전/구성에서 다음에 대한 호출memcmp로 인정될 것입니다.__builtin_memcmp. 방출하는 대신call에게memcmp라이브러리 함수, GCC는 최적화된 인라인 버전의 기능을 수행하기 위한 몇 가지 명령을 발표할 것입니다.

x86의 경우에는cmpsb명령어는 한 메모리 위치의 바이트 문자열을 다른 메모리 위치와 비교합니다.이것은 다음과 결합되어 있습니다.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가 가지고 있는 최신 명령어 세트를 (런타임 시) 감지하고 이에 최적화된 버전을 실행한다는 것입니다.다음에서 이 토막글을 참조하십시오.

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)

리눅스 커널에서

리눅스는 최적화된 버전을 가지고 있지 않은 것 같습니다.memcmpx86_64의 경우에는 적용됩니다.memcpy, 에서 사용할 버전을 런타임에 결정할 뿐만 아니라 부팅 시 한 번만 이 결정을 내릴 수 있도록 패치 자체를 적용하는 대체 인프라스트럭처()arch/x86/kernel/alternative.c를 사용합니다.

일반적으로 컴파일러 인텐셜(intrinsic)은 메모리 블록을 비교하기 위한 전문적인 명령어와 함께 빠른 어셈블리로 변환됩니다.

고유 memcmp

memcmp는 CPU 명령 같은 것입니까?

이것은 적어도 매우 최적화된 컴파일러가 제공하는 고유 함수입니다.플랫폼에 따라 한 개 또는 두 개의 기계 명령이 있을 수도 있습니다. 지정하지는 않았습니다.

언급URL : https://stackoverflow.com/questions/21106801/why-is-memcmp-so-much-faster-than-a-for-loop-check

반응형