AMD 라이젠이 나왔습니다. 지금까지 AMD CPU에선 생각도 할 수 없을 정도로 성능이 좋긴 한데, 모든 점에서 인텔을 앞서는 것도 아니고 단점도 있는 건 사실입니다. https://gigglehd.com/gg/803464
GDC 2017에서 Ken Mitchell(Developer Technology Engineer, AMD)가 강연한 Optimizing for AMD Ryzen CPU는 바로 라이젠을 위한 소프트웨어 최적화에 대한 것입니다.
우선 라이젠의 명령어 셋트를 봅시다. 라이젠은 7세대 APU인 브리스톨 릿지에서도 지원하지 않았던 다수의 인텔 확장 명령어 셋트를 지원합니다. 예를 들어 덧셈을 연속으로 실행할 것을 고려하고 플래그를 취급하는 덧셈 명령인 ADX는 인텔이 브로드웰 세대에서 도입한 것인데 라이젠도 지원하기 시작했습니다.
반면 AMD 고유의 확장 명령어인 FMA4, TBM, XOP는 지원하지 않습니다. AMD CPU에서만 쓸 수 있으니 소프트웨어 개발자들이 지원에 소극적이었다고 합니다. 이들 명령 셋트는 지원이 중단되면서 앞으로 나올 AMD CPU에서도 보긴 어려울 것입니다.
또 한가지 흥미로운 화제는 라이젠의 캐시입니다. 라이젠은 코어마다 L1 명령 캐시 64KB, L1 데이터 캐시 32KB, L2 캐시 512KB를 갖추고, 4개의 코어가 8MB L3 캐시를 공유하는 CPU 컴플렉스(CCX)라는 구조를 씁니다. 8코어 모델인 라이젠 7이 2개의 CCX를 갖고 있으니 L3 캐시는 총 16MB가 됩니다.
라이젠 7의 캐시는 경쟁 상대보다 대역폭이 뛰어나지만 레이턴시는 떨어지는 결과가 나왓는데, AMD는 라이젠의 캐시가 경쟁 상대보다 뛰어나다고 주장했습니다. 그 이유는 L1, L2, L3 캐시의 레이턴시가 모두 낮기 때문이라고. 위 표에서 레이턴시는 4~40클럭 사이클로 결코 늦지 않습니다.
AMD가 제시한 결과를 보면 캐시 레이턴시는 라이젠과 인텔의 L1 데이터 캐시는 같고, L2에선 인텔이 낮지만 L3에선 라이젠이 낮습니다. 그럼 왜 벤치마크 결과 https://gigglehd.com/gg/820955 와는 다를까요? 그건 뭐 다른 이유가 있겠죠.
CPU 아키텍처와 성능 측정에 사용하는 명령을 표시한 슬라이드입니다. DF(데이터 패브릭)은 메모리 컨트롤러와 I/O를 중개하는 부분으로 CPU 코어 측 성능은 RDPMC 명령으로 볼 수 있습니다. 참고로 메모리 컨트롤러와 I/O 컨트롤러는 NDA가 걸려 있어서 공개 불가.
이제 본론이라고 해도 되겠네요. 라이젠엔 XFR이라는 기능이 있어 CPU 쿨러의 성능이 좋고 TDP에 여유가 있다면 부스트 클럭을 넢어서도록 동작이 가능합니다. 그런데 라이젠 7이 최대 부스트 클럭을 초과해서 작동하려면 8개의 CPU 코어 중 6개 이상이 C6 스테이트까지 떨어져야 합니다. C6은 딥 파워 다운이라 불리는 것으로 아이들 상태입니다. 즉 여러 코어에 적당한 부하가 가해지는 게임이나 애플리케이션에선 XFR의 작동 조건을 충족시켜 최대 부스트 클럭을 넘기가 어렵다고 합니다.
위 도표는 라이젠 7 1800X의 동작 클럭 패턴을 나타낸 것으로 ACPI P 스테이트가 3.6GHz, 3.2GHz, 2.2GHz의 3단계가 P3 스테이트이며 C 스테이트에 따라 4단계 부스트 클럭이 나오곤 합니다. 모든 코어가 활성화된 상태에선 부스트 클럭은 기본 클럭보다 고작 100Mhz 높은 3.7GHz며, 싱글 스레드 애플리케이션에선 최대 4.0GHz입니다.
또 라이젠의 성능은 운영체제의 전원 관리 설정과도 밀접한 관련이 있습니다. 윈도우 10의 전원 관리 탭에서 고성능으로 설정하면 모든 CPU 코어의 P 스테이트가 최고값인 P0으로 고정되고, OS 스케줄러도 전력 사용량을 따지지 않고 모든 CPU 코어를 사용하는 상태가 됩니다. 또 CPU 부하가 낮을 때 사용하지 않는 코어를 멈추는 코어 피킹 기능을 무효화합니다.
오른쪽 아래에서 '윈도우 10이라면 1ms 이하로 동작 클럭을 제어한다'는 말은 인텔 CPU에서도 마찬가지입니다.
그리고 전원 관리 옵션을 균형으로 설정하면 코어 피킹이 활성화돼, 피킹된 코어를 피해서 전력 효율을 높이도록 OS 스케줄러를 바꿉니다. 이 상태에선 CPU에 걸리는 부하가 높아져 코어 피킹을 해제하려 해도 최고 속도까지 올라가는 데 30ms가 걸립니다. 이는 AMD가 전원 관리 설정을 고성능으로 설정하라고 권장하는 이유입니다.
사실 코어 피킹으로 인한 성능 저하는 인텔 CPU에서도 충분히 가능한 이야기이기도 합니다.
동작 클럭, 바이오스, 윈도우 10의 설정에 대한 주의사항입니다. 바이오스에서 P-스테이트를 최고값인 P0, 코어 퍼포먼스 부스트와 글로벌 C 스테이트 컨트롤은 끄고, 윈도우 10의 전원 설정을 고성능으로 두라는 것. CPU의 전력 제어용 컨트롤러인 시스템 매니지먼트 유닛은 P0 스테이트에 고정 전력을 공급하게 합니다.
다음은 다이렉트 X 12입니다. https://gigglehd.com/gg/803181 여기서 말한 것도 있으니 간단히 요약하면 다이렉트 X 12를 쓰는 것만으로 CPU의 성능을 끌어내진 못한다네요. 다이렉트 X 12는 스레드 단위로 GPU 큐를 처리할 수 있어 멀티스레드 효율이 높아진다는 게 일반론이나, 꼭 그런 건 아니라고 합니다.
위 슬라이드는 마이크로소프트의 샘플 코드를 사용해 드로우 컨텍스트의 수와 성능을 표시한 것입니다. 드로우 수가 1025일 때 드로우 컨텍스트는 2~3으로, 더 늘려도 성능이 떨어진다고 합니다. 그리고 드로우를 10배로 늘려 10250개가 되면 드로우 컨텍스트는 7 정도가 최적의 값이 됩니다. 그 이상은 역효과를 낼 뿐.
드로우 컨텍스트 수는 stdafx.h에서 NumContexts라는 상수로 설정돼 있습니다.
그리고 AMD는 드로우 수를 300으로 나눈 값고, 스레드 수에서 1을 뺀 값을 비교해서 둘 중 작은 값을 드로우 컨텍스트 수로 쓰는 게 좋다고 해결책을 제시했습니다. 그럼 라이젠 7에서 SMT가 활성화되고 드로우 수가 크다면 드로우 컨텍스트는 15가 나오겠네요. 다만 이건 어디까지나 다이렉트 X 12를 대상으로 한 이야기며 다이렉트 X 11 게임과는 상관이 없습니다. 그리고 게임 개발자가 생각할 문제니까 일반 사용자와는 상관이 별로..
그리고 캐시에 미리 데이터를 불러오눈 프리페치 명령은 쓰지 않는 게 좋다고도 합니다. 라이젠의 캐시 시스템은 충분히 효율이 좋기에 프리패치를 쓰면 캐시 루프가 정상 작동하지 ㅇ낳는다고 하네요.
work()는 고정 루프로 프리페치가 없으면 컴파일러가 루프를 전개하나, 프리페치를 넣으면 루프가 돌지 않아 결과적으로 느려진다고 합니다.
프리페치 계열 명령 셋트는 AMD가 1998년에 나온 K6-2에서 처음으로 채택한 확장 명령 셋트인 3DNow!에 포함됐습니다. 이게 인텔 CPU에도 도입돼 윈도우 8이후에선 꼭 필요한 명령 셋트가 됐네요. AMD가 제안한지 19년이 지나서야 보급이 제대로 된 셈이지만.
AMD의 프로파일인 CodeXL의 라이젠 지원 버전은 조만간 발표할 거라고 하니 프로그래밍 하시는 분들은 https://github.com/GPUOpen-Tools/CodeXL 여길 참조.