안녕하세요~


이번글에서는 내장그래픽과 외장그래픽에 대해서 알아보면서 그래픽카드의 내부구조 동작 방식에 대해 간단히 알아보도록 할거에요. 

그리고 딥러닝을 돌리시다보면 CUDA memory allocation error 라는 메시지 또는 GPU 메모리 관련 메시지가 발생하는데 이러한 이유에 대해서도 알아보도록 하겠습니다~







<1.딥러닝에서 GPU가 필요한 이유>


행렬과 같은 연산을 할때 CPU는 각각의 행렬 elements들을 순차적으로 계산하게 됩니다. 그런데, 행렬이 연산되는 방식을 보면 굳이 순차적으로 할 필요없이 각각의 elements들을 병렬적으로 계산할 수 있다는 사실을 알 수 있어요. 


단순히 3D 그래픽 처리를 위해 고안된 그래픽카드가 오늘날 tensor 계산을 기본으로 하는 딥러닝 연산에 최적으로 적용된셈이죠. (딥러닝 구조가 대부분 numpy 패키지로 구성되어 있다는 점 아시죠?ㅎㅎ)


<사진1>







<2.내장그래픽 VS 외장그래픽>


그래픽카드를 이야기할때 보통 내장그래픽과 외장그래픽으로 나누게 됩니다.


내장그래픽은 보통 CPU 내부에 있는 그래픽카드를 의미하고, 외장그래픽은 CPU 외부에 있는 그래픽카드인 셈이죠. (CPU 내부에 있나, 외부에 있나 그 차이에요!)


사실 내장그래픽만으로도 배틀그라운드 같은 게임도 충분히 돌아가지만 좀 더 생동감 넘치는 게임을 하기위해서는 더 높은 사양의 그래픽 카드를 필요로 해요. 그렇기 때문에 대부분 외장그래픽을 구매해서 모니터와 연결한답니다.


<사진2>



이는 게임뿐만아니라 앞에서 했듯이 딥러닝 또는 복잡한 과학계산을 할 때도 마찬가지로 그래픽카드가 이용됩니다. 그런데 왜 오늘날 딥러닝 모델을 학습시키기 위해서 내장 그래픽이 아닌 외장그래픽을 사용하게 되는걸까요? 







<3.내장그래픽>


CPU의 내장그래픽이 동작하려면 CPU와 마찬가지로 메모리에서 데이터를 읽어들여와야 합니다. 

CPU는 메인메모리 전부를 자신의 공간처럼쓰지만 내장그래픽은 함부로 그렇게할수가 없어요. 그렇기 때문에 내장그래픽이 메인메모리의 일부를 자신의 전용메모리로 사용할건지, 공유해서 사용할할건지 사전에 결정해야 한답니다.


"내PC->오른쪽 마우스 클릭 -> 속성" 으로 접속하시면 가끔 실제 메모리보다 적은 양의 메인메모리가 사용가능하다고 나오는데 이는 메인메모리의 일부(0.11=8.00-7.89)가 내장그래픽의 전용메모리로 잡혀있기 때문이에요. 


<사진3>




하지만 제 컴퓨터 같은경우는 전용메모리로 잡아둔게 없네요. 그렇다면 메인메모리의 일부를 공유하고 있다는 말인데, 어떻게 확인할 수 있을까요?




"작업 관리자 -> GPU(내장그래픽) -> 성능 탭"을 보시면 메인메모리의 절반인 2G를 공유메모리로 사용하고 있어요 ㅎㅎ




그런데 생각해보세요. 딥러닝 모델이 보통 많은 용량을 차지하는데 이 모델을 학습시킬때 메인메모리에 올리고 내장그래픽이 사용한다고 하면 CPU가 과부하 걸리지 않을까요? 

또한 내장그래픽카드의 연산능력은 당연히 CPU크기가 커지지 않는한 비약적으로 좋아지진 않을거에요. 


차라리 외부에 장치를 두어서 그래픽 또는 병렬계산을 해주는 장치를 따로 두는게 좋지 않을까요? 그 장치에는 더 큰 용량의 전용메모리를 주면 CPU가 부담을 덜 수 있지 않을까요? 


위와같은 질문을 통해 오늘날 GPU라고 인식하고 있는 외장그래픽이 등장하게됩니다!





<4.외장그래픽>


앞선 질문들에 대한 해답으로 외장그래픽이라는 개념이 등장하게 됩니다.


우리가 흔히 보는 GPU는 외장그래픽을 의미합니다.

외장그래픽이 하는일은 병렬계산과 같은 일을 CPU가 던져주면 해당 내용을 자신들의 전용메모리인 VRAM에 저장시킵니다. 그리고 GPU에서 VRAM에 접근해 작업을 처리하게 됩니다. 쉽게 말해 외장그래픽에서 CPU역할을 GPU가, RAM역할을 VRAM이 한다고 보시면 됩니다.  

<사진4>



외장그래픽카드도 공유메모리를 이용할 수 있지만 전용메모리(Directed GPU memory usage)크기가 내장그래픽보다 큰것을 볼 수 있죠?




외장그래픽에 자체메모리를 두는 또 다른 이유는 고속연산을 하기 위해서에요. 일반 메인메모리는 기본적으로 많은 양의 process를 올려서 CPU가 언제든지 접근할 수 있게 준비해주는게 필요하고, GPU는 특정 계산을 고속으로 처리해주어야 하기 때문에 메인메모리보다는 작지만 외장그래픽 내부에 자체 메모리를 두어 메모리 접근에 대한 물리적 거리를 단축시켜주게 됩니다.



이렇게 자체메모리를 두기 때문에 딥러닝 같은 모델을 GPU에 올려놓고 학습데이터들을 GPU에 batch size만큼 올려주게 됩니다. 그런데 GPU의 메모리가 적다면 무거운 딥러닝 모델도 올리지 못할거에요. 딥러닝 모델을 올린다고 하더라도 잔여 메모리양(= 기존 VRAM - 딥러닝 모델 용량)이 많지 않기 때문에 training dataset의 batch size를 크게 잡아서 학습을 진행시키면 "CUDA allocation error (GPU 메모리양이 부족하다는 뜻)" 메시지가 출력된답니다. (batch size가 딥러닝 일반화 성능에 크게 영향을 미친다는 논문도 발표된거 보면 GPU의 메모리가 얼마나 중요한지 아시겠죠?)




딥러닝을 위해서는 CPU보단 GPU가 더 중요한것 같은데, 그렇다면 아래와 같은 질문에 대해선 어떻게 생각하시나요?


"Q.CPU는 저사양으로 사용해서 돈을 절약하고, GPU만 고사양으로 사서 컴퓨터를 맞추면 되나요?"


결론부터 말씀드리면.....

 

"A.GPU 성능과 CPU의 성능차이가 많이 나면 서로간에 통신을 할때 병목현상이 생기기 때문에, 어느정도 서로 스펙을 맞춰줘야해요!"


그럼 이제부터 GPU와 CPU간의 병목현상이 왜 생기는지 알아보도록할게요!





<5.GPU와 CPU간 병목현상>


아래 그림처럼 GPU가 일을 하기 위해서는 CPU로부터 작업을 할당받아야해요.

외장그래픽(여기서부터는 GPU라고 할게요)에는 자신의 자체 메모리(ex:VRAM)이 있어요. GPU또한 CPU와 비슷한 역할을 하기 때문에 어떤 작업을 하기 위해서는 메모리에 접근해야해요. 그래서 CPU가 DMA를 통해 GPU가 작업할 일을 GPU의 메모리(VRAM; 아래그림에서는 Device memory)에 올려두게 됩니다.



<사진5>




1) 병목현상의 원인1 - CPU와 GPU간의 성능차이


앞서 GPU는 CPU에게서 작업을 할당받는다고 했죠? 

만약 작업이 마무리되면 어떻게 될까요?

물론 다시 CPU에게 자신의 작업이 완료됐다는 사실을 알리고 CPU는 이에 따른 작업을 수행하기 될거에요.



<사진6>



그런데 만약 CPU는 성능이 낮아 다른 업무들도 빠르게 처리하기 버거운데, 성능좋은 GPU는 자신의 작업을 빠르게 마무리하게 계속해서 CPU에게 주면 어떻게 될까요? 결국 CPU는 할일이 쌓여만 가는데 우선순위 때문에 GPU관련된 task를 수행하지 못하고 있을거에요. 


사람입장에서는 CPU가 GPU의 일을 빨리 처리해주지 못하다보니 "GPU의 성능이 좋지않군" 이렇게 판단하게되고 GPU는 굉장히 억울한 입장에 놓일거에요.


이렇게 CPU가 성능이 떨어져 GPU의 성능을 뒷받침 하지 못하는 경우를 CPU와 GPU간의 병목현상이라고 부른답니다.



Bottleneck calculator(링크)에 접속하시면 아래와 같은 그림이 생성되요.



굉장히 낮은 성능의 CPU와 높은 성능의 GPU를 컴퓨터에 세팅한다고 하면 얼마나 큰 병목(bottleneck)이 생길까요?



대략 46%의 Bottleneck이 생긴다고 하네요.


  





친절하게 i7-8700k에 해당하는 CPU로 바꾸는게 좋겠다고 추천까지해주니 편하네요!








2) 병목현상2 - PCI Bus (Peripheral Component Interconnect Bus) = PCIe(express), (feat.NVLink)


앞에서 언급한 CPU와 GPU간의 병목현상의 또 다른 원인이 되는것이 PCI Bus에요.


PCI Bus는 RAM과 VARM 사이의 데이터 전송 통로입니다. 


<사진7.위에서부터 4, 16, 1, 16 레인>




기본적으로 PCIe bus의 성능이 좋지 않으면 VRAM에 전달해주는 데이터속도가 빠르지 않을거에요.


<사진8>




<사진9>






<사진10. CPU 스펙의 한 부분을 차지하는 PCIe version>








만약 Multi-GPU(ex; GPU1, GPU2)를 사용할 경우 GPU1과 GPU2가 서로 통신하려면 어떻게 해야할까요? 그냥 서로 통신하면 될 것 같은데, PCIe로 구성된 구조에서는 GPU1에서 PCI bus를 거쳐 다시 GPU2로 전송되게 됩니다.


이렇게 되면 GPU1, GPU2가 서로 직접적으로 통신하는것 보다 더 많은 시간이 소요될 수 있어요 (PCIe를 한 번 거친다는건 물리적 거리가 소용된다는 말이니까요)







이러한 문제를 해결하기 위해 NVLink를 지원해주는 GPU가 등장했는데요. NVLink는 쉽게 말해 GPU간의 통신을 빠르게 해주기 위해 GPU들을 연결해주는 장치라고 생각하시면 될거에요.


<사진11>


PCIe 3.0 레인의 전송속도는 8GT/s 인 반면에, NVLink는 20Gbit/s (PCIe 3.0 대비 2.5배) 전송속도를 자랑하며, GPU1&GPU2 인접한 GPU간의 전송은 40Gbit/s 라고 합니다 (GT/s = Gbit/s 라고 간주하셔도 됩니다)



<사진12>



<사진13. PCIe VS NVLink 속도차이 with ResNet-50>





3) GPU 내부에서 발생하는 병목현상



GPU는 VRAM으로부터 데이터를 받아 연산을 수행하게 됩니다. 


많은 양의 데이터가 VRAM에서 GPU로 이동할때 시간이 좀 걸리겠죠? 

만약 GPU 할당받은 작업을 굉장히 빨리 끝낸다면 어떻게 될까요?


VRAM에서 GPU로 데이터를 이동시키고 있는 도중에 GPU가 이미 작업을 끝낸다고 하면 GPU 입장에서는 "나 일다 끝났는데 왜 빨리 다음일을 안주는거야.. 이러면 내가 놀게되잖아.."라고 하소연하며 VRAM이 작업물을 빨리 넘겨주지 않는다고 생각할거에요.




이러한 문제를 해결하기 위해서는 VARM에서 GPU 넘기는 대역폭이 커야해요. 대역폭이 크면 데이터를 빠르게 전송할 수 있게 되고, GPU가 작업을 마무리함과 동시에 새로운 데이터를 줄 수 있게 됩니다.







지금까지 내장그래픽과 외장그래픽의 차이에 대해서 알아보았어요.

또한 외장그래픽(GPU+VRAM+etc..) 성능을 극대화시키기 위해서는 어떤 요소들이 필요한지도 알아봤습니다.



다음 글에서는 간단하게 GPU의 구조에 대해 설명해보도록 할게요! 

GPU 구조를 아주 간단히 보여드리고 이를 뒷받침해주는 CUDA, cuDNN 이라는 병렬처리 플랫폼(or 소프트웨어)을 소개하도록 하겠습니다!~





 






[글 래퍼런스]

https://blog.inten.to/hardware-for-deep-learning-part-3-gpu-8906c1644664

책: 머신러닝과 블록체인을 떠받치는 GPU의 모든 기술



[사진 래퍼런스]

사진1,2

https://www.youtube.com/watch?v=tsB97IAejbk

사진3

https://m.blog.naver.com/PostView.nhn?blogId=ryujava&logNo=30168166523&proxyReferer=https:%2F%2Fwww.google.com%2F

사진4

http://www.11st.co.kr/product/SellerProductDetail.tmall?method=getSellerProductDetail&prdNo=2875791125&gclid=Cj0KCQjwiYL3BRDVARIsAF9E4Gd6siIhHGLIX6uQ_AgjVXK3XSvGI1T2f8VZ4NNaEfzJM7P7eztBvAIaAr53EALw_wcB&utm_term=&utm_campaign=%B1%B8%B1%DB%BC%EE%C7%CEPC+%C3%DF%B0%A1%C0%DB%BE%F7&utm_source=%B1%B8%B1%DB_PC_S_%BC%EE%C7%CE&utm_medium=%B0%CB%BB%F6

사진5

https://insujang.github.io/2017-04-27/gpu-architecture-overview/

사진6

https://www.slideshare.net/RenaldasZioma/trip-down-the-gpu-lane-with-machine-learning-83311744

사진7

https://m.blog.naver.com/PostView.nhn?blogId=rkalstn2&logNo=30180069244&proxyReferer=https:%2F%2Fwww.google.com%2F

사진8

https://blog.naver.com/alias_maya/20201203156

사진9

https://www.digitalcitizen.life/pci-express-pcie

사진10

https://www.anandtech.com/show/8426/the-intel-haswell-e-cpu-review-core-i7-5960x-i7-5930k-i7-5820k-tested

사진11

http://www.noteforum.co.kr/news/index.htm?nm=28621

사진12

http://playwares.com/sponsornews/57567833

사진13

https://www.pugetsystems.com/labs/hpc/TensorFlow-Performance-with-1-4-GPUs----RTX-Titan-2080Ti-2080-2070-GTX-1660Ti-1070-1080Ti-and-Titan-V-1386/

+ Recent posts