programing

n++가 n=n+1보다 빨리 실행되는 이유는 무엇입니까?

javajsp 2023. 10. 1. 19:18

n++가 n=n+1보다 빨리 실행되는 이유는 무엇입니까?

C언어로, 왜?n++보다 빨리 실행n=n+1?

(int n=...;  n++;)
(int n=...;  n=n+1;)

오늘 수업에서 우리 선생님이 그 질문을 하셨습니다.(이것은 숙제가 아닙니다)

'석기시대' 컴파일러 작업을 하고 있다면 그럴 겁니다

"석기 시대"의 경우:
++n보다 빠릅니다.n++보다 빠릅니다.n=n+1
기계는 보통.increment x게다가add const to x

  • 의 경우n++, 2개의 메모리만 액세스할 수 있습니다(읽기 n, incn, 쓰기).
  • 의 경우n=n+1, 3개의 메모리 액세스(읽기 n, 읽기 const, add n and const, 쓰기)가 가능합니다.

하지만 오늘의 컴파일러는 자동으로 변환됩니다.n=n+1로.++n, 그리고 그것은 당신이 상상할 수 있는 것보다 더 많은 것을 할 것입니다!!

또한 오늘날의 고장난 프로세서에서는 - "석기시대" 컴파일러의 경우에도 불구하고 - 런타임은 많은 경우에 전혀 영향을 받지 않을 수 있습니다.!!

관련된

GCC 4.4.3 for x86에서는 최적화 여부와 상관없이 정확히 동일한 어셈블리 코드로 컴파일하므로 실행에 동일한 시간이 걸립니다.조립에서 볼 수 있듯이, GCC는 단순히 변환합니다.n++안으로n=n+1, 그런 다음 하나의 명령어 추가(-O2)로 최적화합니다.

선생님의 제안에 따르면n++faster는 매우 오래된 최적화되지 않은 컴파일러에만 적용됩니다. 이 컴파일러는 인플레이스 업데이트 지침을 선택할 만큼 똑똑하지 않았습니다.n = n + 1. 이 컴파일러들은 PC 세계에서 몇 년 동안 사용되지 않았지만, 여전히 이상한 사유 임베디드 플랫폼에서 발견될 수 있습니다.

C 코드:

int n;

void nplusplus() {
    n++;
}

void nplusone() {
    n = n + 1;
}

출력 어셈블리(최적화 없음):

    .file   "test.c"
    .comm   n,4,4
    .text
.globl nplusplus
    .type   nplusplus, @function
nplusplus:
    pushl   %ebp
    movl    %esp, %ebp
    movl    n, %eax
    addl    $1, %eax
    movl    %eax, n
    popl    %ebp
    ret
    .size   nplusplus, .-nplusplus
.globl nplusone
    .type   nplusone, @function
nplusone:
    pushl   %ebp
    movl    %esp, %ebp
    movl    n, %eax
    addl    $1, %eax
    movl    %eax, n
    popl    %ebp
    ret
    .size   nplusone, .-nplusone
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

출력 어셈블리(-O2 최적화 포함):

    .file   "test.c"
    .text
    .p2align 4,,15
.globl nplusplus
    .type   nplusplus, @function
nplusplus:
    pushl   %ebp
    movl    %esp, %ebp
    addl    $1, n
    popl    %ebp
    ret
    .size   nplusplus, .-nplusplus
    .p2align 4,,15
.globl nplusone
    .type   nplusone, @function
nplusone:
    pushl   %ebp
    movl    %esp, %ebp
    addl    $1, n
    popl    %ebp
    ret
    .size   nplusone, .-nplusone
    .comm   n,4,4
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

컴파일러가 최적화됩니다.n + 1무일푼으로

말입니까?n = n + 1?

만약 그렇다면, 이들은 동일한 어셈블리로 컴파일됩니다. (최적화가 켜져 있고, 표현이 아닌 문장이라고 가정할 때)

누가 그러대요?당신의 컴파일러는 모든 것을 최적화해서, 정말로, 그것을 무트 포인트로 만듭니다.

현대의 컴파일러는 두 양식을 동등한 것으로 인식하고 목표 플랫폼에서 가장 잘 작동하는 형식으로 변환할 수 있어야 합니다.이 규칙에는 한 가지 예외가 있는데, 바로 부작용이 있는 가변 접근입니다.예를 들어, 만약n메모리 mapped 하드웨어 레지스터입니다. 이 레지스터를 읽고 쓰는 것은 단순히 데이터 값을 전송하는 것 이상의 일을 할 수 있습니다(예를 들어, 읽기는 인터럽트를 제거할 수 있습니다).당신은 사용할 것입니다.volatile드에 대한 하는 데 입니다.n는 와 할 수 .n++ 및 )dn = n + 1(작업 읽기, 추가 및 저장).그러나 정규 변수의 경우 컴파일러는 두 양식을 동일한 것으로 최적화해야 합니다.

그렇지 않습니다.컴파일러는 대상 아키텍처에 맞는 변경을 수행합니다.이와 같은 마이크로 최적화는 종종 불확실한 이점을 갖지만, 중요한 것은 프로그래머의 시간적 가치가 없다는 것입니다.

사실 그 이유는 사후 수정의 경우 사업자가 사전 수정의 경우와 다르게 정의되기 때문입니다.++n시키고 "에 대한 "n"를 "n"합니다를는합니다.n++는 "을 증가시켜 "n"이고마다 "n"합니다.constn"사의 ). , 구문,n = n + 1더 효율적일 것입니다.하지만 저는 위 포스터들에 동의해야 합니다.좋은 컴파일러는 사용하지 않는 반환 개체를 최적화해야 합니다.

에서 C 의 .n++식들은 정의상 다음의 부작용과 동등합니다.n = n + 1표현. 하기 때문에, 이라는 것은 , 이 는 어떠한 이 없기 에, BTWT코드가 오직 부작용에만 의존하기 때문에, 이러한 표현식이 항상 정확히 동등한 성능을 갖는다는 것이 정답이라는 것은 즉각적으로 명백합니다. (컴파일러의 최적화 설정에 관계없이, 이 문제는 어떠한 최적화와도 전혀 관련이 없기 때문입니다.)

컴파일러가 의도적으로(그리고 악의적으로) 이러한 차이를 도입하려고 할 경우에만 이러한 표현식의 성능에 대한 실질적인 차이가 발생할 수 있습니다.그러나 이 경우에는 물론 컴파일러의 작성자가 원하는 대로 어느 쪽이든 갈 수 있습니다.

소프트웨어라기보다는 하드웨어 문제에 가깝다고 생각합니다.이전 CPU에서는 n=n+1이 두 개의 메모리 위치를 필요로 하는데, 여기서 ++n은 단순히 마이크로컨트롤러 명령어입니다.하지만 현대 건축에 적용될 수 있을지는 의문입니다.

이 모든 것들은 컴파일러/프로세서/컴파일 지시에 달려있습니다.따라서 "일반적으로 더 빠른 것"이라는 가정을 하는 것은 좋은 생각이 아닙니다.

언급URL : https://stackoverflow.com/questions/2884762/why-does-n-execute-faster-than-n-n1