스택큐힙리스트

프로세서 폭의 배수가 아닌 uop 개수를 실행하는 루프를 실행할 때 성능이 감소하나요? 본문

카테고리 없음

프로세서 폭의 배수가 아닌 uop 개수를 실행하는 루프를 실행할 때 성능이 감소하나요?

스택큐힙리스트 2023. 10. 26. 12:26
반응형

나는 최근 x86 프로세서에서 다양한 크기의 루프가 uop의 수에 따라 어떻게 수행되는지 궁금합니다.


다른 질문에서 이 문제를 제기한 Peter Cordes의 인용문이 여기 있습니다. (원본 링크):



루프가 4의 배수가 아닌 경우 루프 버퍼에서 루프 외의 uop 대역폭이 일정하지 않으며(예: abc, abc, ...; abca, bcab, ...가 아님), Agner Fog의 마이크로아키텍처 문서에서 이 루프 버퍼의 이러한 제한에 대해 명확하지 않게 설명되어 있습니다.



문제는 루프가 최대 uop 처리량으로 실행되기 위해 N개의 uop의 배수 여부입니다. 여기서 N은 프로세서의 너비입니다. (예: 최근 Intel 프로세서의 경우 4입니다). 너비와 uop 카운트에 대해 다룰 때 복잡한 요소가 많지만, 나는 주로 그러한 것들을 무시하고 싶습니다. 특히, 마이크로 혹은 매크로 퓨전은 고려하지 않는다고 가정합니다.

피터는 다음의 예시를 사용하여 7 개의 uop을 갖는 루프를 설명합니다:



7 개의 uop 루프는 4|3|4|3|... 그룹으로 이루어질 것입니다. 저는 루프 버퍼에 맞지 않는
큰 루프를 테스트해보지 않아 다음 반복의 첫 번째 명령이 같은
그룹에 있는 taken-branch와 함께 수행될 수 있는지 여부는 검증하지 않았지만, 그럴 수 없을 것이라고 가정합니다.



일반적으로, 본 주장은 본문에 있는 x 개의 uop을 갖는 루프의 각 반복이 ceil(x / 4) 번의 반복을 수행하며, 단순히 x / 4 번만 수행하는 것이 아니다는 것입니다.


이것은 최근 x86 호환 프로세서들 중 일부 또는 모두에 적용되는 사실인가요?

답변 1

7 재미로 Firefox에서 perf stat을 실행하여 탭을 열고 몇 가지 Stack Overflow 질문을 클릭했습니다. 전달된 명령에 대해, DSB에서 46%, 레거시 디코더에서 50%, LSD에서 4%를 얻었습니다. 이는 적어도 브라우저와 같이 큰 분기 코드에서 DSB가 여전히 대다수의 코드를 포착하지 못한다는 것을 보여줍니다(다행히 레거시 디코더는 나쁘지 않습니다).


8 이를 의미하는 바는 다른 모든 사이클 카운트가 유효한 합성 루프 비용을 uops로 가져와 4로 나눔으로써 설명될 수 있다는 것입니다(실제 크기보다 높을 수 있는 uops). 아주 짧은 루프의 경우에는 이 작업이 작동하지 않습니다 - 임의의 정수를 4로 나누어서 반복당 1.333 사이클에 도달할 수는 없습니다. 다른 방식으로 말하면, 모든 다른 영역에서 비용은 어떤 정수 N에 대해 N/4 형태를 가지고 있습니다.

9 사실 스카이레이크는 레거시 디코더로부터 5개의 uop을 사이클당 전달할 수 있는 것으로 알려져 있지만, 그 5개의 uop이 5개의 다른 명령어에서 오는지, 아니면 4개 또는 더 적은 명령어에서 오는지는 알 수 없습니다. 즉, 우리는 스카이레이크가 2-1-1-1 패턴으로 디코딩할 수 있다고 예상하지만, 1-1-1-1-1 패턴으로 디코딩할 수 있는지는 확실하지 않습니다. 위의 결과는 스카이레이크가 실제로 1-1-1-1-1로 디코딩할 수 있다는 증거를 일부 제공합니다.

답변 2

반복문의 uop(마이크로 연산) 수가 프로세서의 크기의 배수가 아닌 경우 실행 성능이 감소되는가?
프로그래밍을 할 때, 효율성과 성능은 항상 중요한 요소입니다. 반복문은 코드의 일부를 반복해서 실행하는데 사용되는 구조입니다. 그러나 반복문의 uop(마이크로 연산) 수가 프로세서의 크기의 배수가 아닌 경우, 성능에 영향을 미칠 수 있다는 의문이 제기됩니다. 이에 대해 자세히 알아보겠습니다.
반복문은 코드를 반복해서 실행함으로써 특정 작업을 수행합니다. 예를 들어, 배열의 각 요소를 확인하거나 특정 작업을 여러 번 수행해야 할 때 반복문이 유용합니다. 하지만 반복문이 프로세서의 크기에 맞지 않는 uop 수로 구성되어 있다면, 프로세서가 올바르게 동작하지 못하거나 성능 저하가 발생할 수 있습니다.
프로세서는 명령어 당 여러 개의 마이크로 연산을 동시에 실행할 수 있습니다. 이를 위해 프로세서는 여러 개의 실행 유닛을 가지고 있으며, 각 유닛은 특정 유형의 마이크로 연산을 처리하기 위해 설계되었습니다. 예를 들어, 정수 연산 및 부동 소수점 연산을 위한 별도의 유닛이 존재합니다. 따라서, 프로세서의 크기는 해당 유닛의 수와 동일합니다.
반복문은 일정한 횟수만큼 반복되므로, 이를 원활하게 실행하려면 프로세서의 크기와 일치한 uop 수로 이루어져야 합니다. 그렇지 않으면 프로세서의 실행 유닛 중 일부는 비어 있는 상태로 남게 되며, 이는 프로세서의 자원을 비효율적으로 사용하는 결과를 낳을 수 있습니다. 바로 이러한 이유로 반복문의 uop 수가 프로세서의 크기의 배수가 아닌 경우, 성능 저하가 발생할 수 있습니다.
반복문의 uop 수를 프로세서의 크기의 배수로 맞추기 위해 몇 가지 방법을 사용할 수 있습니다. 첫째, 반복문 내의 코드를 최적화하여 uop 수를 줄일 수 있습니다. 예를 들어, 반복문 내부에서 불필요한 연산을 제거하거나 루프 불변 임시 변수를 제거하는 등의 최적화 기법을 적용할 수 있습니다. 둘째, 반복문의 횟수를 프로세서의 크기의 배수로 맞추는 방법이 있습니다. 이는 데이터 블록 크기를 변경하거나 블록 단위로 반복문을 실행하는 등의 방법을 통해 구현할 수 있습니다.
결론적으로, 반복문의 uop 수가 프로세서의 크기의 배수가 아닌 경우 실행 성능이 저하될 수 있습니다. 따라서, 프로그래머는 반복문을 작성할 때 uop 수가 최적화되도록 고려해야 합니다. uop 수를 최적화하는 방법을 사용하고, 프로세서의 크기와 관련된 요구 사항에 주의하여 코드를 작성하는 것이 중요합니다. 이를 통해 프로그램의 성능을 향상시킬 수 있고, 프로세서의 자원을 효율적으로 활용할 수 있습니다.

반응형
Comments