Saturday, August 16, 2008

CUDA shared memory와 coalesced memory access

오랫만에 CUDA 포스트.

뭔가 새로운 것을 배워나갈때 좋은 방법중에 하나는 잘 만들어진 예제를 참고하는 것이다. CUDA의 경우에는 SDK에 꽤나 좋은 예제가 많아서 배울 때 도움이 많이 된다.

그 중에 Convolution예제는 반드시 봐 두면 좋을 것 같은 예제다. 우선 원래 알고리즘이 매우 직관적이고 Serial implementation이 간단해서 원래 뭐였는지 고민할 필요가 없다는 점이 좋고, CUDA로 대충 구현했을때도 간단히 할 수 있지만 생각보다 속도가 나오지 않으며, 예제의 구현을 따라가면 훨씬 효율적으로 구현할 수 있음을 확인하면서 일반적인 CUDA 구현을 배울 수 있기 때문에 그렇다.

이번 포스트에서 생각해보고자 하는 것은 왜 나이브한 구현이 느려지는지와 shared memory의 사용에 대한 것이다. CUDA를 이용해 GPU를 구동했을 때 빨라지는 것은 거의 thread의 수가 늘어나는 것과 메모리 활용에 달려있다. 가능한 한 많은 thread를 동시에 구동할 수 있게 하는 것과, memory access pattern을 디자인하는 것이 속도 향상을 꾀할 때 필요한 것이다.

thread의 갯수는 거의 알고리즘의 복잡도에 달려있는데 이는 총 thread의 수가 각 thread내에서의 레지스터와 블럭 내의 shared memory사용량에 달려있기 때문이다. 다른 한 가지 요소는 coalesced memory access를 할 수 있는가이다. coalesced memory access는 각 thread가 메모리의 연속된 값에 접근할 때 한꺼번에 가져오거나 쓰는 것을 말하는데, 몇 가지 요구사항이 만족될 때만 이루어진다. 이를 coalescing requirement라고 하는데, 프로그래밍 가이드에 나와있기로는,
1) 각 thread가 32, 64, 128비트(4,8,16바이트) 워드를
2) thread number N인 thread가 (HalfWarpBaseAddress + N)에 접근하고
3) HalfWarpBaseAddress가 16*sizeof(type) 바이트의 주소 구조를 가지는 경우
이다.

그러나 모든 알고리즘이 이런 조건을 만족시킬 수 없으므로 성능은 생각보다 저하된다. 어떤 경우에는 데이터를 먼저 정렬시켜 넘겨줌으로써 가능할 수도 있지만 정렬에도 시간이 걸리며, 가능하지 않은 경우도 많다. 이 같은 경우 shared memory를 버퍼로 사용하여 메모리에 접근하면 눈에 띄는 성능 향상을 얻을 수 있다.

기본적인 아이디어는 각 thread를, 1)데이터 수집, 2) 프로세싱, 3) 데이터 저장 의 세 단계로 만드는 것이다. 데이터 수집단계에서는 필요한 data를 parallel thread를 써서 coalescing access하여 shared memory buffer에 가져오고, 프로세싱 단계에서는 이 데이터를 처리해서 다른 shared memory에 담고, 저장 단계에서는 프로세싱된 데이터를 다시 coalescing access로 global memory에 돌려주는 것이다. 각 단계 사이에 thread동기화를 통해 데이터를 확실히 얻도록 해야 한다. 불필요한 동작이 많은 것 같아 보이지만 메모리 접근횟수가 확실히 줄어들고 shared memory는 매우 빨리 읽고 쓸 수 있기 때문에 더 빠른 구현이 가능해진다. multiplication이나 convolution 예제에서는 이런 데이터 접근에 대해서 상세히 설명하고 있다.

빠른 버퍼를 두어서 데이터 접근 패턴을 바꾸는 것은 반드시 알아두어야 할 테크닉으로 이를 통해서 약 10배의 속도향상을 얻을 수 있다.

다루고 있는 데이터가 4,8,16 바이트가 아닐 경우에는 문제가 약간 복잡해지는데, 이 때는 4,8,16 바이트의 크기를 갖는 char struct를 정의해 두고, type casting을 통해 강제로 읽어들이게 하여 해결해야 한다. 어떤 경우든 인덱싱과 base address요구조건에 신경을 써 줘야만 함에 주의하자.

Thursday, August 14, 2008

열심히 한다는 건...

어쩌면 이런 걸지도 모른다.


어딘가 블로그에서 본 2000년 시드니올림픽의 한 장면.
적도기니의 수영선수 무삼바니는 예선 마지막조에서 두명의 경쟁자를 만났다. 하지만 두 명의 경쟁자들은 부정출발로 실격되고 혼자 100m 자유형 경기를 치르게 된 장면.
그런데, 적도기니라는 나라에는 50m 수영장이 없었기 때문에 무삼바니에게는 이 경기가 50m 풀장에서 해본 첫 번째 경기였다. 게다가, 무삼바니는 수영을 한 게 8개월밖에 안되는 초보자였던 것.

드넓은 풀장에서 홀로 100m를 힘겹게 헤엄치고 있는 그의 모습을 보면서, 저런게 열심히 하는 거구나 싶은 생각이 들었다. 0.1초를 다투는 기록과는 관계가 멀었지만 마지막까지 열심히 하는 모습은, 비록 참가에 의미를 두는 것이었겠지만, 그로서는 최선을 다한 경기였으리라. 마지막에 힘이 빠져 거의 전진하지 못하면서도 끝까지 끝까지 허우적대며 나서는 모습이 아마 모든 관객이 기립박수를 보내게 한 게 아닐지.

이 글을 적고 있는 이 순간에도 펠프스는 접영 예선 경기를 치르고 있다. 그가 이번 올림픽에서 수많은 세계기록을 세우며 최선을 다하는 것처럼, 무삼바니가 홀로 치른 레이스도 최선을 다했다는 점에서는 동일한 것. 이런게 바로 열심히 한다는 것의 감동이다.

(무삼바니는 수영에 꽤나 재능이 있었는지 모르겠다. 4년후 올림픽에는 비자 문제로 참가하지 못했지만, 기록은 57초 이내였다고 하니 정식크기가 없는 나라에서 혼자 연습하는 걸 감안하면 대단히 잘하는 것 같다. 체계적으로 배웠다면 훨씬 더 빠르지 않았을까.)

Reference: http://en.wikipedia.org/wiki/Eric_Moussambani

Wednesday, August 13, 2008

윤하 - 今が大好き(지금이 제일 좋아!)

일본어도 못 하지만, 그저 우리 윤하양의 음성을 듣고 싶어서 들었는 데...
번역된 가사를 읽어 보기 전에도 왠지 무슨 뜻인지 알 것 같았어. 간간이 들리는 단어들 때문일까.
시원스러운 목소리도 맘에 들었지만, 이 가사를 들으면서 왠지 가슴이 벅차오르는 감동. 메시지는 그대로 전해졌나 봐. 궁상이지만 눈물이 조금 맺히기도 하고...

내일 걱정 보다는 오늘을 즐기며 열심히 살고 싶었던 날이 있었던가.
지금을 좋아하면 100점 만점. 지금 하고 싶은, 원하는 일이 있으면 지금 하면 되지.
사실... 내일이란게 올지 안 올지도 모르는 거고, 매일매일 내일이 왔으니까 내일이 온다는 보장도 없는데다가... 잠들기 전에 아침에 일어나지 않기를 기도하곤 하지만... 그럴 수록 오늘 하루가 중요하잖아. 내일은 없을 지도 모르는 걸.

하긴 당장 죽어도 크게 맘에 걸리는 것은 없다는 것 하나가 위안이긴 하지만. 그래도 윤하처럼 지금이 제일 좋다고 외치고 싶은 날을 더도 말고 딱 하루 정도는 더 맞았으면 싶기도 하다.

긍정적인 가사랑 시원한 목소리, 즐거운 멜로디가 모두 즐거운 노래~

Monday, August 11, 2008

냉정한 눈으로

연구를 하는 사람으로 가져야 할 가장 기본적인 것이 무엇일까 생각해 보았다. 아마도 어떤 경우에도 냉정한 눈을 갖는 것이 가장 기본이 아닐까 싶다. 하지만, 역시나 사람인지라 항상 그리 되기가 힘든 것이 사실.

존경하옵는 지도교수님께서 해 주신 이야기. 학생들이 보통 저지르는 실수는 '자기 합리화'. 쉽게 말하면 핑계를 만들어 내는 것. 어떤 알고리즘을 제안하고 구현하는 과정에서 수없이 많은 실수를 저지르게 되고 대부분의 시간은 그 오류를 수정하는데 들어가게 되는 것이 사실이다. 물론 구현 과정에서 일어난 사소한 실수들이 잘못된 결과를 얻어내는 큰 이유. 그런데 재미있는 것은 많은 학생들이 잘못된 결과가 나오는 이유를 구현상의 실수로 생각하기 보다는 알고리즘 자체의 문제로 보는 경우가 많다는 것이다.실제로는 매우 발생하기 어려운 이상한 경우를 만들어서 이런 경우에는 제안한 알고리즘이 동작하지 않는다고 예단하고 만다는 것. 아마도 사소한 구현 실수를 하지 않았다고 생각하고 싶은 마음이 그런 핑계거리를 만들어 내는 것은 아닐지. 보통 많은 알고리즘이 그런 특수한 경우가 존재하므로 그건 자신의 문제가 아니라고 미뤄두고 싶은 그런 마음이리라.

논문을 쓸 때도 마찬가지. 분명 논문을 쓴 자신이 가장 자기 논문의 문제점이 뭔지, 약한 부분이 뭔지 알고 있을 것임에도 불구하고 보통은 냉정한 눈을 갖지 못하고 합리화를 서두르고 만다. 다른 사람들이 보기에는 앞뒤가 맞지 않거나 논지에 어긋난 것이 분명하지만, 스스로 눈을 감고 마는 것이 아닌지... 오래전에 썼던 논문을 다시 들춰보게 되어 읽어보니 그때보다는 냉정한 눈이 되었는지 얼굴이 화끈거린다.

돌아온 한 해의 첫 날. 좋은 소식으로 맞이했으면 더 좋았겠지만, 더 이상 기다리지 않아도 된다는 것도 나쁘지 않아. 이제는 버릴 건 버리고, 먹고 살 일을 고민해야 할 때가 정말 온 거 같다.

Sunday, August 10, 2008

수영에서 금메달을!

설마설마 했던 일이 일어나고야 말았네.. 헐 정말 대단하다고 밖에 말할 수 없다.

개인적으로는 올림픽이나 아시안게임이 국가대항전처럼 되고 '우왕 우리나라 짱이야!'하는 분위기가 되는 걸 좋아하지 않는다. 다분히 국가주의적인 접근이기도 하고 특히나 우리나라처럼 엘리트체육인 상황에선 그저 애국심 고취를 위한 것이되기 마련이다. 물론 정말 열심히 연습해서 세계에서 뭔가를 최고로 잘하는 사람이 된다는 건 존경할 만한 일이지만, 그 사람보다는 그 사람의 국가가 우리나라이기에 주목받아야 한다는 건 좀 이상한 일이기도 하다.

뭐 어쨌든... 그럼에도 불구하고 계속 그렇게 살아온 사람으로써 한국사람이 금메달을 딴다거나 이기는 걸 보면 더 좋은 것도 사실이고... 아마 한국방송에서 메달 가능성이 큰 종목을 중심으로 보여준 영향도 큰 것 같다. 잘 볼 수 없었던 조정이나 승마경기를 미국에서 중계해주는 걸 보니 더 그렇네.

하여간, 어린 생각에는 절대 못할거라 생각했던 종목이 수영자유형, 피겨스케이팅, 육상단거리였는데, 연아랑 박태환이라는 괴물들이 나와버림으로써 두 종목에서 세계 수준 선수가 나와버렸다. 뭐 엘리트체육이건 어쨌건간에, 불가능할 거라 생각했던 일들이다. 내 기준으로는 김연아랑 박태환이 해낸일은 육상200m에서 우승하는 거나 비슷하다. 미국에 와서 인간들의 덩치가 어떤가를 보고나서라 그런가 이건 말도 안되는 일. 특히나 몸 하나로 하는 기초종목인 수영이나 육상에서 세계 최고가 된다는 건... 보면서도 이해하기 어려운 일. 얼마나 힘들게 해냈을지는 스타트 실수로 먼저 짐을 싸던 4년전의 박태환과 지금의 모습을 비교해보면 적나라하다.

세상은 이렇게 바뀌어가고 있다. 저런 어린 훈남, 훈녀들이 얼마나 더 많을지. 어리지만 정말 존경스럽다.

(그러고보니 박태환을 비롯한 수영선수들은 전부 겨드랑이털을 깔끔히 밀었군. 실제로보면 좀 징그러울려나 ㅎㅎ)