2015-01-09 4 views
2

CPU 및 코드 최적화에 대한 자세한 내용은 어셈블리 프로그래밍을 공부하기 시작했습니다. 또한 CPU가 스스로 속도를 높이는 "분기 예측"과 같은 영리한 최적화에 대해서도 읽었습니다."goto"문은 CPU의 "분기 예측"에 어떤 영향을 줍니까?

아직 주제를 잘 모르기 때문에 내 질문이 어리석은 것처럼 보일 수 있습니다.

CPU의 분기 예측과 잘 맞지 않기 때문에 (인터넷상의) goto 문은 프로그램의 성능이 저하된다는 매우 모호한 기억이 있습니다. 그러나 이것은 내가 만든 것으로 실제로 읽지 않은 것일 수도 있습니다.

사실 일 수 있다고 생각합니다. 나에게

int function(...) { 
    VARIABLES DECLARED HERE 

    if (HERE IS A TEST) { 
     CODE HERE ... 
    } else if (ANOTHER TEST) { 
     CODE HERE ... 
    } else { 
     /* 
     Let us assume that the CPU was smart and predicted this path. 
     What about the jump to `label`? 

     Is it possible for the CPU to "pre-fetch" the instructions over there? 
     */ 
     goto label; 
    } 

    CODE HERE... 

label: 
    CODE HERE... 
} 

은 매우 복잡한 작업처럼 보인다 : 나는 그렇게 생각하는 이유

나는 명확하게이 예제 (의사 C에서)를 바랍니다. 그 이유는 CPU가 그곳에 명령을 프리 페치 (pre-fetch) 할 수 있기 위해서 goto이 inorder로 점프하는 장소를 찾아야하기 때문입니다.

이것에 대해 아는 것이 있습니까?

+10

'goto'는 분기 예측과 무관 한 100 % 무조건 점프입니다. 분기 예측은 while, for, virtual, 함수 포인터 등의 조건부 분기에 대한 것입니다. –

+0

@Mooing 그러나 분기 예측은 조건부 분기에 포함 된 무조건 점프와 어떻게 상호 작용합니까? 그게 내 질문이다. – wefwefa3

+1

분기 예측은 다른 모든 명령어와 마찬가지로 무조건 점프를 처리합니다. 완전히 무시됩니다. 나는 그 질문을 정말로 이해하지 못한다. CPU 파이프 라인이 어떻게 작동하는지 혼동하고 단순히 잘못된 용어를 사용하고 있습니까? "분기 예측 자"는 무엇을 의미합니까? –

답변

6

분기 예측자는 분기 예측을 예측할 필요가 없기 때문에 무조건 분기는 문제가되지 않습니다.

브랜치 (및 명령 포인터를 변경하는 다른 명령)의 존재는 명령이 항상 선형 순서로 페치되지 않는다는 것을 의미하기 때문에 추측 명령 페치 장치에 약간의 복잡성을 추가합니다. 물론 이것은 조건부 분기에도 적용됩니다.

분기 예측과 추측 실행은 다른 점임을 기억하십시오. 당신은 추측 실행을위한 분기 예측이 필요하지 않습니다. 분기가 수행되지 않는다고 가정 할 때 추측 적으로 코드를 실행할 수 있으며, 분기를 수행 한 경우 해당 분기를 넘어 모든 연산을 취소 할 수 있습니다.그것은 무조건적인 브랜치의 경우에는 특히 어리석은 일이지만 로직을 좋고 단순하게 유지할 것입니다. (IIRC, 이것은 처음 파이프 라인 방식의 프로세서가 작동하는 방식입니다.)

(추측 적 실행없이 분기 예측을 할 수는 있지만 분기 예측 자에게는 아무도 없을 것이므로 실제로는 포인트가 없습니다. 예상치를 알려주는 것입니다.)

예, 조건부 및 조건부 분기는 명령어 가져 오기 유닛의 복잡성을 증가시킵니다. 괜찮아. CPU 아키텍트는 꽤 현명한 사람들입니다.

편집 : 나쁜 옛날에 goto 문을 사용하면 컴파일러가 코드를 최적화 할 수있는 능력에 부정적인 영향을 줄 수 있음이 관찰되었습니다. 이것은 당신이 생각한 것일 수도 있습니다. 현대 컴파일러는 훨씬 더 똑똑하고 일반적으로 goto에 의해 너무 많이 걸리게하지 않습니다.

+0

투기 페치를 사용하지만 사변 실행이 아닌 분기 예측은 틀림없이 승리 일 것입니다. (다시 "나는 추측한다. 그러나 정말로 요점은 없을 것이다"). – danfuzz

+0

@danfuzz 좋은 지적입니다. 여기에서는 실행 명령의 일부로 명령어를 가져 오는 것으로 가정하고 있지만, OOO와 superscalar 실행과 같은 기능을 사용하면 과도한 단순화라고 생각합니다. – Sneftel

1

'파이프 라이닝'으로 인해 실제 분기가 발생할 위치 앞에 분기 명령어 이 실제로 배치 될 수 있습니다. (이것은 컴파일러에서 찾을 수있는 분기 예측 로직의 일부입니다).

goto 문은 단지 점프 명령입니다.

부수적 설명 : 구조적 프로그래밍 개념 코드 명확성, 가독성, 유지 관리 고려 사항 등을 고려하면; 'goto'문을 절대로 사용해서는 안됩니다.

대부분의 CPU에서

, 는 명령의 점프/호출/반환 형식은 새 위치 가 캐시에없는 경우, 새 위치에서 해당 캐시를 다시로드 프리 페치 캐시 을 플래시합니다.

참고 : 항상 '이상'하나의 점프 명령을 포함합니다 작은 루프, 를 들어, 많은 CPU는 실행 전용 그러므로 하나 개의 프리 페치 순서 을 수행하고 프로그래머가 작은 루프를 만들기 위해 을 악용 할 수있는 내부 버퍼를 가지고 크기가 훨씬 빠릅니다.

+3

구조적 프로그래밍에서 goto를 사용해야하는지 여부는이 질문의 주제가 아닙니다. 고토는 구조화 된 프로그래밍 기능이 try..catch 개념이없는 C의 오류 처리/정리와 같은 상황을 지원하지 않을 때 항상 사용될 수 있습니다. –

+1

4 개의 들여 쓰기로 답안의 텍스트를 CODE로 표시했습니다. 하지마. – crashmstr

+0

" 'goto'문을 사용해서는 안됩니다.": 독단적 인 문장입니다. 고토가 최선의 선택 인 상황이 있습니다. (고토는 해로운 것으로 간주되는 유해한 것으로 간주됩니다.) –

관련 문제