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.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의 경우 다음 명령어 집합 확장 기능을 이용할 수 있습니다.
- SSE2 -
sysdeps/x86_64/memcmp.S
- SSE4 -
sysdeps/x86_64/multiarch/memcmp-sse4.S
- SSSE3 -
sysdeps/x86_64/multiarch/memcmp-ssse3.S
멋진 점은 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)
리눅스 커널에서
리눅스는 최적화된 버전을 가지고 있지 않은 것 같습니다.memcmp
x86_64의 경우에는 적용됩니다.memcpy
, 에서 사용할 버전을 런타임에 결정할 뿐만 아니라 부팅 시 한 번만 이 결정을 내릴 수 있도록 패치 자체를 적용하는 대체 인프라스트럭처()arch/x86/kernel/alternative.c
를 사용합니다.
일반적으로 컴파일러 인텐셜(intrinsic)은 메모리 블록을 비교하기 위한 전문적인 명령어와 함께 빠른 어셈블리로 변환됩니다.
memcmp는 CPU 명령 같은 것입니까?
이것은 적어도 매우 최적화된 컴파일러가 제공하는 고유 함수입니다.플랫폼에 따라 한 개 또는 두 개의 기계 명령이 있을 수도 있습니다. 지정하지는 않았습니다.
언급URL : https://stackoverflow.com/questions/21106801/why-is-memcmp-so-much-faster-than-a-for-loop-check
'programing' 카테고리의 다른 글
C switch 문보다 크고 작음 (0) | 2023.11.04 |
---|---|
Angularjs [$rootScope:inprog] 진행 중 오류 발생 (0) | 2023.11.04 |
지원 라이브러리를 이용하여 리플 애니메이션을 달성하는 방법은? (0) | 2023.11.04 |
Swagger / springfox 자동으로 응답 예제 생성 (0) | 2023.11.04 |
응용 프로그램 개발자가 저지른 데이터베이스 개발 실수 (0) | 2023.10.30 |