딱히 논문이나 Intel spec 문서 찾아볼 꺼리라고 생각하진 않았음.
근 20년 전 부터 나는 클럭단위로 코드를 평가해 왔음.
486때까진 대충 어떤 instruction 이 몇 개의 클럭을 차지하는지,
stall 이 어떤경우 발생하는지 외우고 다녔거든.
펜티엄이 나오면서 획기적으로 곱셈 같은것들이 좋아졌고,
슈퍼스칼라와 파이프라인이 도입되면서 파이프라인의 단계가 깊어질수록 single core 병렬화가 좋아졌음.
( 클럭의 세분화라고 보는게 맞지만 )
그러던 어느날 한 15년 전인가,
새 장비에서 클럭을 체크해보니 예년의 두 배로 클럭이 높게 잡히는거임.
이상하게 여겨서 메인보드 메뉴얼을 찾아보니 하이퍼쓰레딩 옵션이 보이더군. 그래서 그걸 껐지.
그러니 클럭이 정상적으로 잡히더군.
그래서 생각했지.
아 하이퍼쓰레딩은 하나의 코어 안에서 매 클럭 스위칭 하면서 동시에 두 가지 쓰레드를 번갈아 실행하는거라,
사실상 클럭 속도는 절반으로 떨어지는 셈이구나. 라고.
요즘은 클럭 측정해보면 3의 배수로 잡힘. ( 또 뭔가 잔뜩 추가 됐겠지 )
그러니까, 여러분은 클럭속도가 절반이고 코어가 두 배인데,
메모리나 레지스터 처럼 코어 내 공유자원 접근시 약간 방해를 받는 모드를 선택할지
아니면 클럭속도가 하이퍼쓰레딩의 두 배인 코어를 선택할지 정해야 한다는 것.
만약 2클럭이상 정도가 필요한 연산들을 대량으로 계산해야 하는 경우 ( 이미지 처리 처럼 )
병렬화가 이점이 생기는거임.
반면에 앞의 연산을 결과를 이어받아 계산해야하는 종속적이고 그 흐름이 많지 않은 계산들은
하이퍼쓰레딩을 꺼야 정상적인 클럭으로 실행이 되는 것이지.
이것도 내부로 들어가면 아키텍쳐마다, 그리고 어떤 연산을 사용하느냐에 따라 또 유불리가 나뉘어져.
그러니 확실한 케이스를 나눠 알아 두는게 좋겠지.
하이퍼 쓰레딩이 유리해지는 좀 쉬운 예를 들어보자.
( 파이프라인은 일단 무시하고 )
a 연산의 결과를 얻는데 2 클릭이 필요하고, 그 결과를 A 라고 표현해 보면,
A =a* a
B =b* A ( A 종속 )
-------
C =c* c
D =d* C ( C 종속 )
( =a* 이게 명령어 하나라고 표현한거임 )
와 같은 4개의 명령이 있다고 가정할때
hyper thread mode 에서는
clock ->
hyper thread0 : aAbB_
hyper thread1 : _cCdD
처럼 계산되겠지.
non-hyper thread 에서는
clock ->
single core : aAcCbBdD
처럼 처리 되는 것. 즉 전자는 5clock 후자는 8clock 을 소요하게 되지.
근데 하나의 스트림에서 처리되어야 하는 계산이었다면,
thread0 와 thread1 의 결과를 합쳐야 되는 비용이 너무 크니까
그냥 하이퍼 쓰레드 하나는 놀고 한놈만 뺑이 치게 되는거지.
어차피 2클럭 연산들이었다면 그래도 좋은데, 만약 1클럭 연산들이 섞여 있을 경우
clock->
hyper thread0 : A B C D
hyper thread1 : 놀자
이렇게 되어버리고 반대의 경우는
single core : ABCD
이렇게 되어버리는거지.
공학용 계산에 흔히들 하이퍼 쓰레딩을 끄고 계산한다고 하더라만,
뭐 내가 보기엔 종속성이 커서 동기화 시켜야하는 경우나 아니라면,
float 와 double 류들을 SIMD 의 도움 없이 대량 처리하는건 하이퍼쓰레딩이 유리하리라고 봄.
( 2클럭 이상 소요되거든 )
아 슈발 졸려서 도저히 정신집중이 안된다.
나중에 또 써 줄께!
병렬 공부중인데 재밌는 글이네요.
나중에 다른이야기도 해주세여
"나와 나머지 3대장인 야이미친과 사랑돋긔는 완전한 상하관계에 있다. 나머지 두명이 불이라면 나는 마그마다" - 프갤 3대장 코세
ㅊㅊ
하이퍼쓰레기
쓸 줄 모르면 쓰레기지
개추 - dc App
simultaneous multithreading
ㄴ 윗글의 주제와 연관된 좋은 키워드다.