부등식 연산자가 같음 연산자보다 빠릅니까?
나는 이것이 마이크로 최적화라는 것을 알고 있으므로 순수한 호기심에서 묻습니다.
논리적으로 마이크로 프로세서는 "FALSE"결과를 결정하기 위해 같음 연산자의 두 피연산자의 모든 비트를 비교할 필요가 없습니다.
이것은 프로그램의 실행 속도에 영향을 미치기 때문에 프로그래밍과 관련이 있습니다.
일반적으로 마이크로 프로세서는 전기 게이트를 사용하여 비교를 수행하며 단계별로 수행하지 않습니다. 한 번에 모든 비트를 확인합니다.
이는 플랫폼에 따라 다르지만 일반적으로 동일하게 수행됩니다.
예를 들어 X86에서는 어셈블리 작동 방식을 살펴보면이를 확인할 수 있습니다. X86 어셈블리 제어 흐름 작업을 확인하십시오. 동일 또는 부등을 수행하는지 여부에 관계없이 두 작업으로 수행됩니다.
먼저 CMP (비교) 작업을 수행합니다. 그런 다음 비교가 같거나 같지 않은지 등을 확인합니다. 이것은 단지 비교 결과를 확인하는 것입니다. 두 경우 모두 두 가지 작업을 수행합니다.
그러나 많은 상위 레벨 프로그래밍 언어에서는 상황이 다릅니다. 많은 언어가 불평등을 평등으로 정의합니다. 불평등을 확인하기 위해 평등 확인을 수행 한 다음 두 번째 확인을 수행하여 거짓인지 확인합니다. 이로 인해 이러한 언어에서 평등이 (미시적으로) 더 빨라집니다. 많은 언어에서 두 가지 모두를 구체적으로 작성할 수 있습니다.하지만 많은 사람들이 평등의 관점에서 불평등을 쓰는 경향이 있습니다. 이는 평등을 일반적으로 약간 더 빠르게 만듭니다.
Intel 64 및 IA-32 아키텍처 최적화 참조 설명서를 읽어야 할 것 같습니다 .
사용하는 지침에서 "파이프 라인 지연"및 "파이프 라인 지연"을 찾으십시오. int로 수행하는 모든 작업은 실행하는 데 약 1 클럭 사이클이 필요합니다 (초당 40 억 개). 메모리에서 데이터를 읽는 것은 작업중인 데이터의 양에 따라 100-1000이 걸릴 수 있습니다. 훨씬 더 중요합니다.
비교는 일반적으로 결과를 무시하는 빼기로 구현됩니다. CPU의 가산기는 모든 비트에서 동시에 작동하므로 이것은 일정한 시간 작업입니다.
그런 다음 평등은 출력이 0인지 여부를 결정하는 것입니다. x86에는 비교 결과로 설정된 플래그가 있으며 분기는 jz 또는 jnz를 통해 수행됩니다 (0이면 점프, 0이 아니면 점프). 따라서 실제 속도 차이는 없습니다.
다른 플랫폼 (예 : ARM 및 IA64)은 유사하게 작동합니다.
다른 답변에서 알 수 있듯이 지침 자체는 동일한 속도로 실행됩니다.
차이가 발생할 수있는 부분은 분기 예측 또는 캐시 효과입니다. 이것은 프로세서마다 다르고 컴파일러마다 다르므로 일반화하는 것은 불가능합니다. 이것이 차이를 만들 수있는 수준에 있다면 알 수있는 유일한 방법은 시도하고 측정하는 것입니다.
비교 작업은 마이크로 프로세서 클록 신호의 상승 (또는 하강) 에지에서 발생합니다. 그런 다음 다음 작업은 다음 클럭 사이클에서 발생합니다. 따라서 실행 속도 측면에서 평등과 불평등은 오늘날 시장에 나와있는 거의 모든 프로세서에 대해 동일한 시간이 걸립니다.
클럭 기반이 아니라 작동 시간 기반으로되어있는 일부 프로세서에 대해 읽었던 것을 기억하기 때문에 거의 말 했으므로 실제로 비교 작업이 추가 작업보다 빠르 다면 n 개의 비교 세트가 보다 적은 시간이 소요될 것입니다. n이 추가됩니다. 하지만 저는 그것이 상업적인 제품이 아닌 연구 프로젝트 일 뿐이라고 99 % 확신합니다. :)
효과가있을 수있는 몇 가지 사소한 경우가 있습니다.
ARM 프로세서 (32 비트 / 비 thumb 명령어 세트 아키텍처 (ISA)의 경우)에서 모든 명령어는 조건부입니다. 때로는 여러 조건에도 불구하고 단일 분기 (끝에서 시작까지)가있는 내부 루프로 벗어날 수 있습니다. 논리적 비교 ( TEQ
)가 있는 몇 가지 경우에는 몇 가지 플래그 (음수 (N) 및 0 (Z)에 영향을 주지만 캐리 (C) 또는 오버플로 (V)에는 영향을주지 않음)를 방해하여 털이 많은 코드가 분기 명령을 피할 수 있습니다 (해제되지 않음). .
반대로 IIRC (실제로 프로그래밍 한 적이 없지만 10 년 전에 C 컴파일러의 출력을 살펴 보았습니다) 68000에는 레지스터 D4에 대해서만 리터럴 EOR / XOR 명령이 있습니다. 따라서 산술 비교는 아마도 더 좋을 것입니다 (여전히 외부 플래그를 무시할 수는 있지만-요점은 명령어 세트가 약간 불규칙하다는 것입니다).
이전 포스터에서 언급했듯이 대부분의 작업은 메모리, 디스크, 네트워크 및 웹 서비스 대기 시간이 더 높습니다.
이것을보다 일반적인 질문으로 제기하려면 TRUE 및 FALSE 답변의 합리적인 분포를 고려해야하며 레지스터보다 긴 것을 포함하여 임의의 단어 길이를 고려해야합니다.
검색 알고리즘 (및 정렬은 검색의 확장으로 간주 될 수 있음)에서 "=="보다 "<"또는 "<="와 같은 연산자를 사용하는 것이 더 일반적입니다. 이는 "=="연산자의 결과 분포가 "거짓"쪽으로 치우쳐있는 경향이있어서 실행 당 엔트로피가 낮기 때문입니다 (즉, 낮은 정보 수율). 이는 동일한 정보를 얻기 위해 더 많은 시간을 실행해야 함을 의미합니다.
두 경우 모두 O (워드 길이) 수의 비트 비교를 취하지 만, 워드 길이가 <= 레지스터 길이 인 경우 비교는 병렬로 수행되며 캐리 전파에 약간의 지연이있을 수 있습니다. (사실, 제가 생각하는 것처럼, 전형적인 불평등의 경우, 어느 쪽이든 첫 번째 불평등 비트에서 멈출 수 있고, 평등 확률이 충분히 작 으면 아주 일찍 일어날 수 있습니다.)
이와 같은 비교를 수행하는 데 걸리는 시간은 일반적으로 1 클럭 사이클입니다.
32 비트 프로세서는 모든 32 비트를 한 번에 처리합니다. 64 비트는 한 번에 64 비트를 수행합니다.
파이프 라인에 지연 또는 중단이 발생하면 피연산자를 사용할 수없고 가져와야하기 때문입니다. 그것이 가장 큰 오버 헤드가있는 곳입니다. 그러나 이는 프로세서의 아키텍처에 적합한 청크로 수행되었으므로 여전히 32 비트 또는 64 비트 단위로 가져 왔을 것입니다.
모든 사람이 가정하는 한 가지 측면은 그가 레지스터 수준 지침에 대해 이야기하고 있다는 것입니다. 모두가 옳습니다. 기본적으로 CPU 수준의 문제입니다. 그리고 더 높은 수준의 대부분의 작업은 평등에 대한 호출이 무효화됨에 따라 불평등을 작성합니다.
그러나 더 높은 수준에서 질문자의 최적화를 사용하면 두 가지 방식으로 작동합니다. 그것은 평등이 불평등만큼 효율적으로 쓰여질 수 있다는 것입니다.
또한 어셈블리 작업과 관련된 사람들의 관점에서 CMP와 SUB의 유일한 차이점은 플래그가 설정되어 있다는 것입니다. CMP는 같음,보다 작음 및보다 큼을 나타내는 플래그를 반환해야하므로 일반적으로 시스템의 동일한 부분에서 실행됩니다.
'programing' 카테고리의 다른 글
GAC 사용의 장점과 단점은 무엇입니까? (0) | 2021.01.19 |
---|---|
Mercurial : 명령 줄에 여러 줄 커밋 메시지가 표시됩니까? (0) | 2021.01.19 |
Objective-C에서 별표 배치 (0) | 2021.01.19 |
Joda Time으로 시간대를 포함한 날짜를 어떻게 구문 분석 할 수 있습니까? (0) | 2021.01.19 |
SVN 프로젝트에서 Eclipse 프로젝트 파일 무시 (0) | 2021.01.19 |