source

푸시 대 이동 비용(스택 대 메모리 근처), 함수 호출 오버헤드

manycodes 2023. 10. 8. 10:00
반응형

푸시 대 이동 비용(스택 대 메모리 근처), 함수 호출 오버헤드

질문:.

스택에 액세스하는 속도가 메모리에 액세스하는 속도와 같습니까?

예를 들어 스택 내에서 몇 가지 작업을 수행하도록 선택하거나 메모리의 레이블이 지정된 위치에서 직접 작업을 수행할 수 있습니다.

따라서 구체적으로 다음과 같습니다.push ax와 같은 속도로mov [bx], ax? 마찬가지로pop ax와 같은 속도로mov ax, [bx]? (assume bx가 위치합니다.near기억력.)

질문 동기:

C에서는 파라미터를 취하는 사소한 함수를 억제하는 것이 일반적입니다.

저는 항상 함수가 돌아오면 매개 변수가 스택에 푸시되다가 스택에서 튀어 나와야 할 뿐만 아니라 함수 호출 자체가 CPU의 컨텍스트를 보존해야 하기 때문에 스택 사용량이 더 많다는 것을 의미한다고 생각해 왔습니다.

그러나 표제가 달린 질문에 대한 답을 알고 있다고 가정할 때, 함수가 스스로 설정하는 데 사용하는 오버헤드(푸시/팝/콘텍스트 유지 등)를 동등한 수의 직접 메모리 액세스 측면에서 정량화할 수 있어야 합니다.그래서 제목이 붙은 질문입니다.


( 편집: Clarification: near used above is as opposed to far in the 세그먼트 메모리 모델 of 16-bit x86 architecture.)

요즘은 당신의 C 컴파일러가 당신을 능가할 수 있습니다.간단한 함수를 인라인으로 처리할 수 있으며 함수 호출이나 반환이 없을 수 있으며 모든 작업을 regi에서 수행할 수 있다면 공식 함수 매개 변수를 전달하고 액세스하는 것과 관련된 추가 스택 조작(또는 함수가 인라인으로 처리되지만 사용 가능한 레지스터가 모두 소진된 경우의 동등한 작업)이 없을 수도 있습니다.또는 결과가 일정한 값이고 컴파일러가 그것을 보고 이점을 활용할 수 있다면 더 좋습니다.

함수 호출 자체는 현대 CPU에서 상대적으로 저렴할 수 있지만 반드시 비용이 0은 아닙니다. 반복되고 별도의 명령 캐시와 다양한 예측 메커니즘이 있다면 효율적인 코드 실행에 도움이 됩니다.

그 외에는 "로컬 var vs 글로벌 var" 선택의 성능이 메모리 사용 패턴에 따라 달라질 것으로 예상합니다.CPU에 메모리 캐시가 있는 경우 큰 어레이나 구조를 할당 또는 할당 해제하거나 딥 함수 호출 또는 딥 재귀가 발생하여 캐시 미스가 발생하지 않는 한 스택은 해당 캐시에 있을 가능성이 높습니다.글로벌 관심 변수가 자주 액세스되거나 해당 인접 변수가 자주 액세스되는 경우 대부분의 경우 해당 변수가 캐시에 있을 것으로 예상됩니다.캐시에 맞지 않는 대규모 메모리에 액세스할 경우 캐시가 누락되고 성능이 저하될 수 있습니다(원하는 작업을 보다 효율적이고 캐시 친화적으로 수행하는 방법이 있을 수도 있고 없을 수도 있기 때문일 수도 있습니다.

하드웨어가 꽤 바보 같은 경우(캐시 없음, 작은 캐시 없음, 예측 없음, 명령 순서 변경 없음, 추측 실행 없음, 아무것도 없음), 각자가 숫자를 셀 것이기 때문에 메모리 압력과 함수 호출의 수를 줄이려는 것은 분명합니다.

그러나 또 다른 요소는 명령어 길이와 디코딩입니다.(스택 포인터에 상대적으로) 온스택 위치에 액세스하는 명령은 주어진 주소에서 임의의 메모리 위치에 액세스하는 명령보다 짧을 수 있습니다.더 짧은 명령은 더 빨리 해독되고 실행될 수 있습니다.

성능은 다음과 같이 좌우되기 때문에 모든 경우에 대해 확실한 답은 없습니다.

  • 당신의 하드웨어
  • 귀사의 컴파일러
  • 당신의 프로그램과 그것의 메모리 접근 패턴.

시계 사이클에 대한 호기심 때문에...

특정 클럭 주기를 보고 싶은 분들을 위해, 다양한 최신 x86 및 x86-64 CPU에 대한 명령/지연 테이블을 여기에서 이용하실 수 있습니다(이것들을 지적해 주신 hirschhornsalz 덕분에).

펜티엄 4 칩을 장착하면 다음과 같습니다.

  • push ax그리고.mov [bx], ax(빨간색 박스)는 동일한 대기 시간 및 처리량으로 효율성이 사실상 동일합니다.
  • pop ax그리고.mov ax, [bx] 상자도 마찬가지로 시)다에도 .mov ax, [bx]이 두 ypop ax

Pentium 4 Instruction Timing Table

댓글의 후속 질문(3번째 댓글)에 대해서는 다음과 같습니다.

  • 지정(, )mov [bx], ax는 직접 지정 ) 는(, )과.mov [loc], ax를 들어 loc 는입니다를 서합니다.loc equ 0xfffd.

결론:이것을 알렉시의 철저한 답변과 결합하면 스택을 사용하는 효율성과 컴파일러가 함수를 인라인으로 처리해야 할 시기를 결정할 수 있다는 확실한 사례가 있습니다.

(부록:사실, 1978년부터 8086년까지 거슬러 올라가더라도, 스택을 사용하는 것은 이 오래된 8086 명령어 타이밍 테이블에서 볼 수 있듯이 메모리에 대응하는 mov의 것보다 여전히 덜 효율적이었습니다.)


대기 시간 및 처리량 이해

최신 CPU의 타이밍 테이블을 이해하기 위해서는 조금 더 필요할 수 있습니다.다음과 같은 이점이 있습니다.

언급URL : https://stackoverflow.com/questions/12766534/cost-of-push-vs-mov-stack-vs-near-memory-and-the-overhead-of-function-calls

반응형