2016-09-25 1 views
0

x86_64에는 64 비트 주소로 직접 점프 할 수 없습니다. 단지 32 비트 만. 간접 점프의 경우 분기 예측이 시작되기 전에 파이프 라인이 한 번 해결되어야한다는 것을 이해합니다. 제 질문은 : 첫 번째 실행에서 1-3 사이클 점프를 수행하는 방법이 64 비트입니까?64 비트 점프의 비용은 항상 처음 10-22 사이클입니까?

답변

2

I- 캐시 미스가없는 경우에도 직접 점프가 항상 "처음"저렴한 것은 아닙니다. 그들은 여전히 ​​분기 예측이 필요합니다. 롱 모드에서


, jcc rel32jmp rel32 (및 rel8 소형 버전)에서 RIP 부호 확장 상대 변위를 사용한다. 2GB 내의 주소에서 오는 한 64 비트 주소로 이동할 수 있습니다. 따라서 rel32 변위를 사용할 수 있도록 코드를 다른 코드의 2GB 내에 두십시오.

긴 모드에서는 절대적인 직접 점프가 없습니다. 32 비트 모드의 far는 JMP ptr16:32 (opcode 0xEA)이고 far CALL ptr16 : 32는 64 비트 버전이 아닙니다. SYSCALL과 INT 같은 명령어는 암시적인 목적지를 가진 간접적 인 점프이며, 어쨌든 유용하지 않습니다. (그리고 성능과 편리 성을 위해 far jmp는 필요 없습니다.)


또한 L1 I-캐시 또는 UOP 캐시, 또는 곧 필요할 주어진 주소의 명령어를 디코딩 파이프 라인을 암시 할 수있는 방법 뜨거운 목표를 얻을 수없는 명령어 프리 페치/프리 디코드 명령이 없습니다. (에뮬레이터의 간접 점프에 대한 내용은 PREDECODE wishlist section in Darek Mihocka's article을 참조하십시오. 한 게스트 명령의 처리기가 다음 게스트 명령의 처리기로 바로 이동하도록하는 것이 유용합니다. 간접 호출 디스패치 명령은 거의 항상 오보 예측됩니다.)


다음 fetch-block이 다른 곳에서 오는 것임을 예측하려면 branch-target-buffer가 필요합니다.. 이 정보는 디코드 단계보다 훨씬 빨라야하므로 중요한 프런트 엔드 거품을 피할 것으로 예측되어야합니다. 흥미로운 질문이 최근이 문제를 야기했습니다 : Slow jmp-instruction. Realworldtech forum thread에 대한 대답은 명령어가 아니라 페치 블록에서 분기 예측이 작동해야한다는 것과 x86에서와 달리 고정 insn 폭 ISA를 간단하게 디코딩하는 경우에도 디코드 결과보다 먼저 예측이 필요하다는 것을 분명히합니다 .


새로 발견 된 직접 (rel32) 점프를위한 코드 페치 버블 크기에 1-3주기가 비현실적입니다. 하지만 거품의 일부는 디코딩 된 uop 큐에 의해 숨겨져있을 수 있습니다.

디코딩 할 코드 가져 오기는 아마도 적어도 5 또는 6 사이클이며 아마도 그 이상일 것입니다. L1-I 히트 시간이 Haswell의 L1D로드 사용 대기 시간과 같은 4 사이클이라고 가정 해 봅시다. 그런 다음 인텔 CPU는 명령 경계를 표시하기 위해 사전 디코딩 한 다음 디코드 단계에서 최대 4 μP를 디코딩합니다. David Kanter's Haswell writeup has a diagram of the frontend. 그 최악의 시나리오이다 있도록 Slow jmp-instruction 질문에서

영업의 데이터는 JMP 명령하지만 아무것도의 거대한 블록 (분기 목표 = 다음 INSN와) 인텔 브로드 웰에 12 개 시계 당 약에서 JMP를 실행 을 나타냅니다 프론트 엔드 시간을 따라 잡을 다른 것을하지 않기 때문에 가져 오기/디코딩 거품을 숨길 수 없습니다.

우리는 기존의 디코더에서 실행하는 것에 대해 이야기하고 있다고 가정합니다. from the uop cache을 실행하는 동안 BTB 미스는 약간 더 짧을 수 있습니다. 왜냐하면 디코딩 된 uop가 더 빨리 사용 가능하기 때문입니다.지점도 uop 캐시에 도달하면 디코딩 된 uop가 디코딩 된 uop 대기열 (루프 버퍼로 사용되는 것과 동일한 버퍼)을 시작할 수 있기 전에 더 적은 사이클이 소요됩니다.

코드 페치 버블 동안 디코딩 된 uop 큐가 비어 있지 않으면 CPU의 순서가 잘못된 부분에 uops를 보내는 발급 단계에 버블이 없을 수 있습니다.

또는 OOO 부품에 실행해야 할 실행 취소 된 uops가 많으면 (예 : CPU가 IPC를 프런트 엔드 대역폭보다 훨씬 적게 제한하는 병목 현상이있는 일부 코드를 실행 중임) 프런트 엔드 버블은 너무 많이 영향을 미친다.


간접 분기가 더 나쁩니다. 정확한 목표는 몇 사이클 후에 최고로 검출 될 수 없습니다. 귀하의 기본 전제가 정확합니다 : 저렴하지 않으며 가능한 경우 피해야합니다.

+2

누군가가 왜 이것이 downvote에 어울리는지를 설명 할 수 있다면, 나는 교정을하게되어 기쁩니다. 나는 이것이 정확하다고 생각하고 그 질문에 가정 된 내용을 다룹니다. –

+0

아주 비슷한 질문이 불과 1 개월 전에 요청되었습니다. 재밌어. 철저한 대답을 해주셔서 감사합니다. – Simon

+0

예, 좋습니다. 나에게서 +1을 가지고 ... 나는 정말로 downvote 추론을보고 싶다. –

관련 문제