32 비트 CPU 모드부터 x86 아키텍처에서 사용할 수있는 확장 주소 피연산자가 있습니다. 베이스 주소, 변위, 인덱스 레지스터 및 스케일링 인수를 지정할 수 있습니다.주소 피연산자는 기계 코드의 성능과 크기에 어떤 영향을 줍니까?
예를 들어, 32 비트 정수리스트를 보폭 싶은 (32 바이트 길이의 데이터 구조의 어레이로부터 모든 처음 두 %rdi
데이터 인덱스,베이스 포인터 %rbx
등).
addl $8, %rdi # skip eight values: advance index by 8
movl (%rbx, %rdi, 4), %eax # load data: pointer + scaled index
movl 4(%rbx, %rdi, 4), %edx # load data: pointer + scaled index + displacement
아시다시피 이러한 복잡한 주소 지정은 단일 기계 코드 명령어에 적합합니다. 그러나 이러한 작업의 비용은 어떻게 독립 포인터 계산을 해결 간단한 비교 않습니다 후자의 예에서
addl $32, %rbx # skip eight values: move pointer forward by 32 bytes
movl (%rbx), %eax # load data: pointer
addl $4, %rbx # point next value: move pointer forward by 4 bytes
movl (%rbx), %edx # load data: pointer
, 나는 하나의 추가 명령 및 종속성을 도입했습니다. 그러나 정수 추가는 매우 빠르며, 더 간단한 주소 피연산자를 얻었으며 더 이상 곱셈이 없습니다. 반면에, 허용 된 스케일링 인자는 2의 거듭 제곱이기 때문에, 곱셈은 비트 쉬프트로 내려 가고, 이것은 또한 매우 빠른 연산입니다. 여전히, 두 개의 덧셈과 비트 쉬프트는 하나의 덧셈으로 대체 될 수 있습니다.
이 두 가지 방법의 성능 및 코드 크기 차이점은 무엇입니까? 확장 된 주소 피연산자를 사용하는 모범 사례가 있습니까?
또는 C 프로그래머의 관점에서 묻는 질문 : 배열 인덱싱 또는 포인터 산술이란 무엇입니까?
는 어셈블리 편집기 크기/성능 튜닝 거기에 의미인가? 각 어셈블리 명령어의 기계 코드 크기, 클럭 사이클에서의 실행 시간 또는 종속 그래프를 볼 수 있었으면 좋겠습니다. 그러한 응용 프로그램의 혜택을받을 수있는 어셈블리 괴물 수천명이 있습니다, 그래서 나는 이미 이와 같은 것이 존재한다고 확신합니다!
일반적인 대답 # 0 : 최적화는 부두입니다. 지침을 추가하거나 긴 지침을 사용하는 등의 작업은 속도가 빨라질 수 있습니다. 이러한 동작은 CPU마다 다를 수 있습니다. 새로운 모델에서 한 모델에 맞는 것이 사실이 아닐 수도 있습니다. 귀하의 경우 상황은 어느 방향 으로든 갈 수 있으며 단순히 측정하지 않고 예측할 수있는 좋은 방법이 없습니다. – Nayuki
일반 답변 # 1 : http://www.agner.org/optimize/; http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html – Nayuki
@NayukiMinase, 일부 유용한 링크. 매우 가치있는 탐색. 감사. – TerryE