• 북마크
  • 추가메뉴
어디로 앱에서 쉽고 간편하게!
애플 중고 거래 전문 플랫폼
오늘 하루 보지 않기
KMUG 케이머그

소프트웨어

[App 개발] CUDA, Supercomputing for the Masses (3)

본문

- 오류처리와 전역 메모리 성능 한계

축하합니다! CUDA 시리즈의 1편과 2편을 마치신 여러분은 CUDA 프로그래머가 되어서 이제 여러분은 CUDA 장치가 지원하는 수백 개의 병렬 쓰레드를 이용한 프로그램을 개발할 능력을 갖추셨습니다. 2편에 소개한 incrementArrays.cu 에서 여러분에게 데이터를 장치에 전송, 계산을 수행하기 위한 커널 실행, 결과 추출이라는 기본적인 CUDA 응용프로그램 패턴의 실행 예제를 보여드렸습니다. 기본적으로 incrementArrays.cu 에 여러분의 계산 커널과 데이터(이번 회에서 소개할 내용)를 집어 넣으시면 어떤 응용프로그램으로도 변형시킬 수 있습니다. 그 다음 회에서는 CUDA 비동기형 I/O 와 스트림에 관해 살펴볼 예정입니다.

"당신은 너무 많은 것을 알고 있소!" 라는 우스개는 지금까지 우리가 공부한 바를 잘 나타내고 있습니다. CUDA 의 좋은 점은 여러분의 프로그래밍 계획을 집단 병렬 프로그램으로 변형하는 자연스러운 방법을 제시하고 있습니다. 하지만 탄탄하고 효율적인 프로그램을 만들기 위해서는 더욱 깊은 이해가 필요합니다.

너무 걱정하지 마시고 시도해 보세요! CUDA 는 프로그래밍 툴이고 훌륭한 소프트웨어를 개발하기 위한 구조물이기도 합니다. 그리고 이것을 배우는 방법은 실제로 해 보는 것 뿐이 없습니다. 실제로 이번 장에서 CUDA 의 특징을 짧은 예제와 여러분의 이해를 돕기 위한 인터넷 상의 정보들을 통해서 여러분에게 실제로 수행해볼 수 있는 방법을 제공하겠습니다. CUDA Zone(http://www.nvidia.com/cuda) 은 CUDA 에 관한 정보와 질문답변을 볼 수 있는 포럼 등을 제공하는 좋은 곳입니다. 그리고 여러분이 직접 질문하고 답변을 얻으실 수도 있습니다.

이번 및 다음 몇 호에 걸쳐서 간단한 배열 뒤집기를 통해서 여러분의 이해를 돕고 공유 메모리가 성능에 미치는 영향을 살펴보겠습니다. 오류 찾기와 성능 검사 등을 CUDA 프로파일링 툴을 이용해서 수행하는 법도 다루겠습니다. 다음 호에 첨부된 소스에서 실제로 배열 뒤집기를 공유 메모리에서 어떻게 수행하는지 보실 수 있습니다. reverseArray_multiblock.cu 는 아직 저성능이지만 CUDA 장치의 광역 메모리 내에서 배열을 뒤집는 법을 보여드릴 것입니다. 하지만 이 프로그램을 여러분의 프로그램에 사용하지는 마세요. 광역 메모리는 이런 종류의 프로그램에 사용하기에 비효율적입니다. 그리고 이 프로그램은 비 연동 메모리 억세스를 하고 있어서 광역 메모리 효율이 좋지 않습니다. 가장 최적의 광역 메모리 밴드폭은 메모리 억세스가 동시에 단일 메모리 교환에 연동되었을 때 얻을 수 있습니다. 다음회에서 광역 메모리와 공유 메모리, 그리고 장치의 계산 능력에 따른 다양한 메모리 억세스 연동 방법을 살펴볼 것입니다.

- CUDA 오류 처리

오류를 발견해서 처리하는 내용은 탄탄하고 실용적인 소프트웨어 개발에 필수입니다. 사람들은 프로그램이 죽거나 오동작하는 것에 대해 관대하지 못합니다. 개발자 측면에서 오류 처리 코드를 넣는 것은 귀찮고 성가신 작업입니다. 그리고 말쑥한 코드를 어지럽히고, 예측 가능한 오류 처리 루틴을 짜는 동안 전체 개발 시간을 지연시킬 수도 있습니다. 네, 오류 처리는 별로 반갑지 않은 작업이지만 이것은 여러분을 위해서 하는 작업이 아니지요 (하지만 잘 만든 오류 처리 코드가 나의 소중한 시간을 아껴주기도 합니다), 이 프로그램을 사용할 사람들을 위해서 하는 작업입니다. 만약 프로그램이 죽으면 사람들은 왜 죽었고, 더 중요한 것은, 어떻게 하면 죽는 것을 방지할 수 있느냐를 알고 싶어합니다. 잘 만든 오류 처리 및 복구 코드는 여러분의 프로그램이 대박 나게 할 것임은 주지의 사실입니다. 상업용 소프트웨어 개발자들은 특히 더 기억해 두세요.

CUDA 를 고안할 때에도 오류 처리의 중요성이 충분히 인식되었습니다. 이를 위해서 커널 호출을 제외한 모든 CUDA 호출은 cudaError_t 라는 오류 코드를 리턴합니다. 작업이 성공적으로 이루어졌으면 cudaSuccess 가 리턴되고, 아니면 오류 코드가 리턴됩니다.

오류 코드를 읽기 쉽게 바꿔주는 것은 다음과 같습니다.

char *cudaGetErrorString(cudaError_t code);

C 언어 프로그래머들은 이 방법과, 오류를 나타내는 변수 errno 와 이를 사람이 읽기 편한 메세지로 변환하는 perror 와 sterror 를 사용하는 C 라이브러리와 유사하다는 것을 발견하실 수 있을 것입니다. 이러한 C 라이브러리 기법은 지금껏 수많은 C 코드에서 애용되어 왔으며, 향후 CUDA 소프트웨어에서도 잘 작동될 것은 의심의 여지가 없습니다.

또한 CUDA 에는 cudaGetLastError 메쏘드가 있어서 호스트 쓰레드의 최후 런타임 콜에 대한 오류를 보고합니다. 여기에는 몇 가지 관련 사항이 있습니다.

* 커널 실행의 비동기성으로 인하여 cudaGetLastError 가 명확하지 않을 수 있습니다. 따라서, 커널 호출을 포함해서 지금까지의 모든 호출이 종료될 때까지 대기했다가 어떤 작업이든 오류가 발생했을 때 오류 코드를 리턴하는 cudaThreadSynchronize 를 사용하세요. 다수의 커널 콜을 동시에 발생시키면 모든 커널 콜이 종료되기 전까지 오류 검사를 할 수 없다는 뜻이 되기도 합니다. 아니면 오류를 검사해서 호스트로 리턴하는 특별한 코드를 직접 커널 내에 작성해 주어야 합니다.
* 오류는 올바른 호스트 쓰레드로 보고됩니다. 만약 프로그램이 다수의 CUDA 장치를 사용하는 경우와 같이, 호스트가 여러 쓰레드를 동시에 실행한다면, 오류는 올바른 호스트 쓰레드로 보고됩니다.
* 만약 cudaGetLastError 를 호출할 때까지 여러 개의 오류가 발생했을 경우, 맨 마지막에 발생한 오류만 보고됩니다. 프로그래머는 실시간을 발생하는 오류 정보를 곧바로 처리해 주어야 합니다. 아니면 잘못된 오류 보고를 사용자에게 출력할 수도 있습니다.

- 소스 코드를 봅시다

reverseArray_multiblock.cu 소스코드를 살펴보시면, 프로그램의 구조는 지난 2편에서 보셨던 moveArray.cu 와 매우 유사하다는 것을 볼 수 있습니다. 오류 처리 루틴 checkCUDAError 는 cudaGetLastError 에서 오류가 보고되었을 때 이것을 읽기 편한 메세지로 출력한 후 프로그램을 종료하는 루틴입니다. 보시는 것처럼 프로그램 전체에 걸쳐서 오류 검사를 위해 checkCUDAError 이 적절히 활용되고 있습니다.

reverseArray_multiblock.cu 는 [0..dimA-1] 의 값을 가지는 1차원 정수형 배열 h_a 를 선언합니다. h_a 는 cudaMemcpy 를 이용해서 장치의 전역 메모리에 상주하는 d_a 로 옮겨집니다. 그리고 나서 호스트는 reverseArrayBlock 커널을 호출하여 d_a 로부터 d_b 로 배열 내용을 역순으로 복사합니다. 그런 다음 장치가 올바른 결과 ([dimA-1..0]) 를 만들었는지 호스트에서 검사합니다.

// includes, system
#include
#include

// Simple utility function to check for CUDA runtime errors
void checkCUDAError(const char* msg);


// Part3: implement the kernel
__global__ void reverseArrayBlock(int *d_out, int *d_in)
{
int inOffset = blockDim.x * blockIdx.x;
int outOffset = blockDim.x * (gridDim.x - 1 - blockIdx.x);
int in = inOffset + threadIdx.x;
int out = outOffset + (blockDim.x - 1 - threadIdx.x);
d_out[out] = d_in[in];
}
/////////////////////////////////////////////////////////////////////
// Program main
/////////////////////////////////////////////////////////////////////
int main( int argc, char** argv)
{
// pointer for host memory and size
int *h_a;
int dimA = 256 * 1024; // 256K elements (1MB total)


// pointer for device memory
int *d_b, *d_a;


// define grid and block size
int numThreadsPerBlock = 256;


// Part 1: compute number of blocks needed based on
// array size and desired block size
int numBlocks = dimA / numThreadsPerBlock;


// allocate host and device memory
size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
h_a = (int *) malloc(memSize);
cudaMalloc( (void **) &d_a, memSize );
cudaMalloc( (void **) &d_b, memSize );


// Initialize input array on host
for (int i = 0; i < dimA; ++i)
{
h_a[i] = i;
}


// Copy host array to device array
cudaMemcpy( d_a, h_a, memSize, cudaMemcpyHostToDevice );


// launch kernel
dim3 dimGrid(numBlocks);
dim3 dimBlock(numThreadsPerBlock);
reverseArrayBlock<<< dimGrid,
dimBlock >>>( d_b, d_a );


// block until the device has completed
cudaThreadSynchronize();


// check if kernel execution generated an error
// Check for any CUDA errors
checkCUDAError("kernel invocation");


// device to host copy
cudaMemcpy( h_a, d_b, memSize, cudaMemcpyDeviceToHost );


// Check for any CUDA errors
checkCUDAError("memcpy");


// verify the data returned to the host is correct
for (int i = 0; i < dimA; i++)
{
assert(h_a[i] == dimA - 1 - i );
}


// free device memory
cudaFree(d_a);
cudaFree(d_b);


// free host memory
free(h_a);


// If the program makes it this far, then the results are
// correct and there are no run-time errors. Good work!
printf("Correct!
");

return 0;
}
void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err)
{
fprintf(stderr, "Cuda error: %s: %s.
", msg,
cudaGetErrorString( err) );
exit(EXIT_FAILURE);
}
}

이 프로그램 구성의 핵심은 배열 d_a 와 d_b 모두 장치의 전역 메모리에 상주한다는 점입니다. CUDA SDK 는 장치의 특성에 대한 약간의 정보를 알 수 있는 bandwidthTest 라는 예제를 제공합니다. 제 시스템에서 전역 메모리 밴드폭은 대략 60 GB/s 를 가리켰습니다. 물론 대단한 값입니다만, CUDA 장치들은 매우 빠른 부동소숫점 계산 기능을 갖춘 128 개의 하드웨어 쓰레드에 데이터를 공급해 주어야 합니다. 32 비트 부동소숫점 값은 4 바이트를 차지하고, 전역 메모리 밴드폭으로 인하여 장치의 계산 능력이 15 GF/s 혹은 사용 가능한 계산 능력의 일부분으로 한정되어 버립니다. (이 결과는 프로그램이 전역 메모리를 읽기만 할 뿐 값을 기록하는 것을 제외했습니다.) 확실히 고성능 프로그램에서는 어떤 방식으로든 데이터를 재사용해야 합니다. 이것이 바로 공유 메모리와 레지스터 메모리의 기능이며, 프로그래머는 이들 메모리를 활용하여 최대 효율을 끌어내야 합니다. 기계에서 부동소숫점 계산 능력과 메모리 밴드폭과의 균형에 대한 이해(혹은 그 외 다른 특성)를 원하시는 분은, 제 글 HPC Balance and Common Sense(http://www.scientificcomputing.com/ShowPR.aspx?PUBCODE=030&ACCT=3000000100&ISSUE=0702&RELTYPE=PR&ORIGRELTYPE=HPCC&PRODCODE=00000000&PRODLETT=E) 를 읽어보세요.

- 공유 메모리 버젼

이번 소스코드는 다음에 소개할 내용이 담긴 코드 arrayReversal_multiblock_fast.cu 입니다. 공유 메모리가 이 문제에 어떻게 적용되는지 보실 수 있도록 이 소스를 지금 제공하겠습니다.

// includes, system
#include
#include

// Simple utility function to check for CUDA runtime errors
void checkCUDAError(const char* msg);


// Part 2 of 2: implement the fast kernel using shared memory
__global__ void reverseArrayBlock(int *d_out, int *d_in)
{
extern __shared__ int s_data[];


int inOffset = blockDim.x * blockIdx.x;
int in = inOffset + threadIdx.x;


// Load one element per thread from device memory and store it
// *in reversed order* into temporary shared memory
s_data[blockDim.x - 1 - threadIdx.x] = d_in[in];


// Block until all threads in the block have
// written their data to shared mem
__syncthreads();


// write the data from shared memory in forward order,
// but to the reversed block offset as before


int outOffset = blockDim.x * (gridDim.x - 1 - blockIdx.x);


int out = outOffset + threadIdx.x;
d_out[out] = s_data[threadIdx.x];
}
/////////////////////////////////////////////////////////////////////
// Program main
/////////////////////////////////////////////////////////////////////
int main( int argc, char** argv)
{
// pointer for host memory and size
int *h_a;
int dimA = 256 * 1024; // 256K elements (1MB total)


// pointer for device memory
int *d_b, *d_a;


// define grid and block size
int numThreadsPerBlock = 256;


// Compute number of blocks needed based on array size
// and desired block size
int numBlocks = dimA / numThreadsPerBlock;


// Part 1 of 2: Compute number of bytes of shared memory needed
// This is used in the kernel invocation below
int sharedMemSize = numThreadsPerBlock * sizeof(int);


// allocate host and device memory
size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
h_a = (int *) malloc(memSize);
cudaMalloc( (void **) &d_a, memSize );
cudaMalloc( (void **) &d_b, memSize );


// Initialize input array on host
for (int i = 0; i < dimA; ++i)
{
h_a[i] = i;
}


// Copy host array to device array
cudaMemcpy( d_a, h_a, memSize, cudaMemcpyHostToDevice );


// launch kernel
dim3 dimGrid(numBlocks);
dim3 dimBlock(numThreadsPerBlock);
reverseArrayBlock<<< dimGrid, dimBlock,
sharedMemSize >>>( d_b, d_a );


// block until the device has completed
cudaThreadSynchronize();


// check if kernel execution generated an error
// Check for any CUDA errors
checkCUDAError("kernel invocation");


// device to host copy
cudaMemcpy( h_a, d_b, memSize, cudaMemcpyDeviceToHost );


// Check for any CUDA errors
checkCUDAError("memcpy");


// verify the data returned to the host is correct
for (int i = 0; i < dimA; i++)
{
assert(h_a[i] == dimA - 1 - i );
}


// free device memory
cudaFree(d_a);
cudaFree(d_b);


// free host memory
free(h_a);


// If the program makes it this far, then results are correct and
// there are no run-time errors. Good work!
printf("Correct!
");

return 0;
}
void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err)
{
fprintf(stderr, "Cuda error: %s: %s.
", msg,
cudaGetErrorString( err) );
exit(EXIT_FAILURE);
}
}

다음 회에서는 성능 향상을 위한 공유 메모리 사용법을 살펴보겠습니다. 그 때까지 __shared__, __constant__, register memory 와 같은 CUDA 메모리 형태에 대해서 살펴보세요.
0 0
로그인 후 추천 또는 비추천하실 수 있습니다.
포인트 228,692
가입일 :
2003-02-18 14:12:30
서명 :
미입력
자기소개 :
미입력

최신글이 없습니다.

최신글이 없습니다.

댓글목록 0

등록된 댓글이 없습니다.
전체 121 건 - 1 페이지
2007.01
27

[App 개발] OpenCV 1.0.0 Frameworks

wlee 님 뿐만 아니라 Mac 에서 이미지 프로세싱 관련 연구를 하시는 분들에게 유용한 툴이 될 듯 싶습니다. 좋은 라이브러리를 알게 되어 wlee 님께 감사말씀 드립니다. ^^ 물론 1.0.0 을 그대로 command-line 으로 컴파일해도…

2006.08
22

[App 개발] 마유라 는 한글이 잘 되는군요. ^^

InputStreamReader 의 속성을 SJIS 에서 EUC-KR 로 바꾸는 방법으로 미와 고스트는 안되는데 마유라 고스트는 잘 되는군요. 인텔 맥에서도 문제없이 돌아가고 있습니다. 영환님도 이미 컴파일 해보셨겠지만, 안되었으면 한 번 …

2005.12
19

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (3)

이번에는 본격적으로 Quartz 의 Core Graphics 를 이용해서 그림을 그려 보겠습니다. 참고 자료로는 애플 홈페이지에서 다운로드 받으실 수 있는 Quartz 2D Programming Guide 입니다. 프로그램의 기본 구조는 이…

2005.12
17

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (2)

윈도우 프로그래밍을 처음 공부한ㄴ 사람들이 한결같이 내놓는 불만은 "왜 이렇게 어렵냐" 라는 것입니다. 막말로, C 에서는 printf("Hello World\\n") ; 요거 하나만 하면 글을 볼 수 있는데, 윈도우에서는 글자 하나를 보…

2005.12
16

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (1)

Xcode 새 버젼의 카본 어플리케이션 템플릿이 좀 더 친절해졌더군요. 한편, 지금까지 자기 고유의 이벤트 핸들러를 갖고 계시던 분들에게는 더 힘들어 졌더군요. ㅠㅠ 자 해 봅시다. 일단. Xcode 를 실행하고, File-&gt;N…

2009.10
22

[App 개발] GCD 예제

MacTech 10 월호에 게재된 GCD 예제를 번역하였습니다. 허락 없는 번역이므로 다른 곳에 퍼 가지 마세요. -_-; *** Grand Central Dispatch Grand Central Dispatch (GCD) 는 개발자들…

2009.09
24

[App 개발] OpenCL 프로그래밍 예제

개인 블로그에 차곡차곡 올리는 도중, 그래도 혹시나 쓸모가 있을 법한 아이를 하나 이곳에 분양하려 합니다. 아직 제 지식과 기술이 일천하여 완전히 최고 속도를 내지는 못하지만, 그래도 공부에는 도움이 될만한 소스가 아닐까 싶습니다. Bili…

2009.09
10

[App 개발] OpenCL 프로그래밍 도중 문제가 생기면...

2차원 Wavelet decomposition 루틴을 작성하기 위해 열심히 노력중에 있습니다. 아직 손에 익지 않은 기술이고, 예제가 많지 않은 기술이라, 매뉴얼 한 권에 의지하여 더듬더듬 나아가고 있습니다. 그런데 정말 신기한 현상을 보게 되었…

2009.08
27

[App 개발] CUDA, Supercomputing for the Masses (8)

- CUDA 와 라이브러리 사용 지난 회에서는 차세대 CUDA 하드웨어를 살펴보았습니다. 이번에는 하드웨어에서 소프트웨어로 주제를 약간 바꾸어서 CUDA 에서 라이브러리를 사용하는 것을 살펴보겠습니다. 최적화된 라이브러리는 응용프로그램의 성…

2009.08
26

[App 개발] CUDA, Supercomputing for the Masses (7)

- 차세대 CUDA 하드웨어 활용하기 6 장에서 CUDA 프로파일러를 이용하여 글로벌 메모리를 확인해 보았습니다. 이번에는 차세대 CUDA 하드웨어에 대해 살펴보려 합니다. CUDA 와 CUDA 지원 장치는 세대를 거듭할수록 더 향상된 성능…

2007.01
27

[App 개발] OpenCV 1.0.0 Frameworks

wlee 님 뿐만 아니라 Mac 에서 이미지 프로세싱 관련 연구를 하시는 분들에게 유용한 툴이 될 듯 싶습니다. 좋은 라이브러리를 알게 되어 wlee 님께 감사말씀 드립니다. ^^ 물론 1.0.0 을 그대로 command-line 으로 컴파일해도…

2006.08
22

[App 개발] 마유라 는 한글이 잘 되는군요. ^^

InputStreamReader 의 속성을 SJIS 에서 EUC-KR 로 바꾸는 방법으로 미와 고스트는 안되는데 마유라 고스트는 잘 되는군요. 인텔 맥에서도 문제없이 돌아가고 있습니다. 영환님도 이미 컴파일 해보셨겠지만, 안되었으면 한 번 …

2005.12
19

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (3)

이번에는 본격적으로 Quartz 의 Core Graphics 를 이용해서 그림을 그려 보겠습니다. 참고 자료로는 애플 홈페이지에서 다운로드 받으실 수 있는 Quartz 2D Programming Guide 입니다. 프로그램의 기본 구조는 이…

2005.12
17

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (2)

윈도우 프로그래밍을 처음 공부한ㄴ 사람들이 한결같이 내놓는 불만은 "왜 이렇게 어렵냐" 라는 것입니다. 막말로, C 에서는 printf("Hello World\\n") ; 요거 하나만 하면 글을 볼 수 있는데, 윈도우에서는 글자 하나를 보…

2005.12
16

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (1)

Xcode 새 버젼의 카본 어플리케이션 템플릿이 좀 더 친절해졌더군요. 한편, 지금까지 자기 고유의 이벤트 핸들러를 갖고 계시던 분들에게는 더 힘들어 졌더군요. ㅠㅠ 자 해 봅시다. 일단. Xcode 를 실행하고, File-&gt;N…

2009.08
25

[App 개발] OpenCL: democracy for GPU computing?

OpenCL: GPU 프로그램의 민주주의인가 by Damien Triolet March 19, 2009 OpenCL 개발 실무진이 꾸려진 지 6 개월 후 Khronos 라는 이름으로 출범하게 되었습니다. 아시는 것처럼 OpenCL (Open …

2009.08
22

[App 개발] Introductory Tutorial to OpenCL

Introductory Tutorial to OpenCL Skip Navigation LinksHome > GPU Tools > ATI Stream SDK > Introductory Tutorial to OpenCL Benedict R. Gas…

2009.08
21

[App 개발] CUDA, Supercomputing for the Masses (6)

- 광역 메모리와 CUDA 프로파일러 이번 6회에서는 메모리 성능과 reverseArray_multiblock_fast.cu 에서 공유 메모리를 사용하는 것을 살펴보겠습니다. 이번에는 CUDA 프로파일러를 이용하여 광역 메모리를 점검할 것입니다.…

2009.08
20

[App 개발] CUDA, Supercomputing for the Masses (5)

- 공유 메모리의 이해 (2) 지난 4회에서 실행 모델과 커널 실행 환경 설정이 레지스터의 갯수와 공유 메모리같은 지역 멀티프로세서 자원에 영향을 미치는지 살펴보았습니다. 이번에는 메모리 성능과 reverseArray_multiblock_fast…

2009.08
19

[App 개발] CUDA, Supercomputing for the Masses (4)

- 공유 메모리 사용법 CUDA 개발자에게 성능 향상의 관건은 공유 메모리, 상수 메모리, 레지스터 등의 프로세서 지역 메모리를 효율적으로 사용하는 것입니다. 앞 장에서 살펴본 것처럼, 전역 메모리 밴드폭이 60GB/s 라고 하지만, 실제 부동소…

2009.08
18

열람중 [App 개발] CUDA, Supercomputing for the Masses (3)

- 오류처리와 전역 메모리 성능 한계 축하합니다! CUDA 시리즈의 1편과 2편을 마치신 여러분은 CUDA 프로그래머가 되어서 이제 여러분은 CUDA 장치가 지원하는 수백 개의 병렬 쓰레드를 이용한 프로그램을 개발할 능력을 갖추셨습니다. 2편에 …

2009.08
17

[App 개발] CUDA, Supercomputing for the Masses (2)

지난 1편에서는 첫 번째 CUDA 예제 moveArray.cu 를 소개하면서 CUDA 툴을 이용하여 프로그램을 만들고 실행하는 것을 연습하였습니다. C 프로그래머에게 그 프로그램은 단순히 CUDA API 를 호출하여 메모리를 할당하여 CUDA 장비와 …

2009.08
16

[App 개발] CUDA, Supercomputing for the Masses (1)

CUDA, Supercomputing for the Masses Rob Farber April 15, 2008 CUDA 는 GPU 상에서 동작하는 소프트웨어를 쉽게 개발하는 기법을 제공합니다. C 와 같은 고급언어를 사용하면서도 멀티코어…

2009.08
15

[App 개발] Mac OS X 커널의 내부 (3)

- 인텔 프로세서 관련 XNU 가 i386 을 지원하기 시작한 것은 90 년대 중반 OpenStep 으로 판매되기 시작할 때부터이지만, Mac OS X 에 적용된 것은 애플이 인텔 프로세서를 채택한 2005/2006 년도부터입니다. 그리고 64 …

2009.08
14

[App 개발] Mac OS X 커널의 내부 (2)

- 아키텍쳐 "XNU" (X is Not Unix) 라는 이름의 Mac OS X 의 커널은 세 가지 요소 (Mach, BSD, I/O-Kit) 로 구성되어 있습니다. - Mach (GNU/HURD 를 제외하고) 아직까지 Mach 코드를…

2009.08
13

[App 개발] Mac OS X 커널의 내부 (1)

Mac OS X 커널의 내부 Mac OS X 에는 마하 커널, 마이크로 커널, FreeBSD 커널, C++, 64 비트, 유닉스,... 그리고 이 모든 것이 포함된 "XNU" 등 여러 전문용어가 담겨있습니다. Mac OS X 커널은 마하 커널도,…

2009.08
12

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (7)

플랫폼 엑스퍼트는 IODTNVRAM 인스턴스를 new 구문으로 직접 생성하고 있으므로 둘은 강하게 연결되어 있습니다. /options 노드는 연결 과정에 참여하고 있지 않고 있으며, 따라서 IODTNVRAM 을 대체할 드라이버를 제공하는 쉬운 방법이 …

2009.08
11

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (6)

- 프로퍼티 조정: 약간의 거짓말이 필요할 때 멤버 변수 외에도 Mac OS X 드라이버에는 IOService (모든 Mac OS X 드라이버의 수퍼클래스) 로부터 상속받은 프로퍼티 테이블을 가지고 있습니다. 프로퍼티를 억세스하는 멤버는 퍼블릭이…

2009.08
09

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (5)

- Mac OS X 업데이트 문제: 오묘한 커널의 세계 기존 드라이버에서 서브클래스를 만들어 우회하는 기법의 가장 큰 장점은 애플이 Mac OS X 를 업데이트 하더라도 커널 익스텐션을 계속 사용할 수 있다는 점입니다. 애플이 제공하는 드라이버를…

2009.08
08

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (4)

- 애플 드라이버 서브클래싱: CD-ROM 충돌이 일어난 경우 Mac OS X 정품을 미 지원 시스템에 설치하는 또 다른 어려운 과제가 바로 스커지 CD-ROM 장치에 CD 를 넣을 경우 시스템 패닉이 일어난다는 점입니다. 이것은 좀 어려운 문제…

2009.08
07

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (3)

- 부팅 과정 따라가기: 정품 인스톨 CD 부팅 PatchedNVRAM.kext 뿐만 아니라 여러 개의 드라이버들을 고치거나 새로 만들어야 합니다. 대략 45,000 줄의 코드 분량의, 모두 30개의 커널 익스텐션을 손보아야 합니다. 미 지…

2009.08
06

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (2)

... 수정된 코드를 PatchedAppleNVRAM 으로 컴파일하는 것은 어렵지 않았습니다. AppleNVRAM 클래스는 짧고 간결했기 때문에, 코드를 복사한 다음 수정해야 할 두 줄만 고쳐 주었습니다. 이제 어떻게 커널이 내 드라이버를 선택하…

2009.08
05

[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (1)

OS X 를 지원하지 않는 기종을 위한 커널 해킹 Ryan Rempel (Other World Computing) - 요약 OS X 가 더 이상 지원하지 않는 기종에서 OS X 를 사용하기 위해서는 커널과 몇 가지 IOKit 익스텐션을 변경해…

2009.02
16

[App 개발] SSE 최적화 (0) 서

맥이 인텔 프로세서를 사용한 지 어언 수 년이 흐르고, 이제 자연스럽게 인텔 프로세서의 장점을 십분 활용하는 방법을 강구하여야 하겠습니다. 예전에 제가 본 게시판에 게재했던 '코드 최적화' 글들을 같이 참조하시면 도움이 되실 것입니다. 대장…

2008.10
14

[App 개발] NSImage 를 비트맵으로 처리하는 방법

제가 아까 잠결에 본 질문글이 있었는데, 다시 자고나서 일어나보니 지우셨나봐요. 질문 내용을 정확히 이해하지 못하고 그냥 얼핏 보았는데, 대략 "NSImage" 객체에서 raw 비트맵 정보를 끄집어내서 작업하고 싶어하시는 것 같던데, 맞나요 …

2007.08
18

[App 개발] 오목 게임 (소스포함)

어떤 분의 요청에 의해 오목게임에 착수한 지 일주일만에 이런 엄청난 게임 -_-;;; 을 만들 수 있다니... 저의 재능에 스스로 놀라면서 (우웩~ -0-;) 카본과 쿼츠 2D 로 만든 초간단 오목 게임입니다. 상당히 멍청한 알고리듬을 탑재하고 …

2007.01
27

[App 개발] OpenCV 1.0.0 Frameworks

wlee 님 뿐만 아니라 Mac 에서 이미지 프로세싱 관련 연구를 하시는 분들에게 유용한 툴이 될 듯 싶습니다. 좋은 라이브러리를 알게 되어 wlee 님께 감사말씀 드립니다. ^^ 물론 1.0.0 을 그대로 command-line 으로 컴파일해도…

2006.11
05

[App 개발] iCal 에 음력 날짜를 출력하자

"한국 달력" 위젯으로 음력 날짜를 확인하셔도 되긴 합니다만, 이왕이면 iCal 에 음력 날짜를 표시해 두면 일정 관리 및 어르신, 친지, 친구 생일 등을 한 프로그램에서 할 수 있으니 편하겠지요 지난번에 iCal 의 파일 포맷을 읽어들이는 루틴…

2006.08
26

[App 개발] iCal 의 데이터를 읽어들이는 초간단 Java 소스

최종 목표는 가짜사과 입니다만 -_-; 혹시나 이런 허접한 소스라도 필요하신 분이 있지 않을까 싶어서 이렇게 올립니다. 눈여겨 보실 클래스는 iCalReader 이고요, iCal 의 데이터를 읽어들이는 루틴을 짧게 구현한 것입니다. O'Re…

2006.08
25

[App 개발] 가짜사과에 내장된 카와리 7 모듈

오늘도 일하다가 몰래 소스를 좀 봤습니다. -_-; 이러다 짤리는걸까 SHIORI Kernels 디렉토리에 있는 SCKawari*.java 가 바로 문제의 "카와리 7" 의 Java 클론이라는데 대충 이렇게 저렇게 살펴보니 대략 세 가지 모…

2006.08
24

[App 개발] 혹시 shioribox 에 관한 정보가 있으면

JNI 에서 시오리 커널을 호출하는 기능 (어떤 설명에서는 커맨드 라인에서도 구동이 가능하다고 하더군요) 을 담당하는 shioribox 모듈에 관한 정보가 좀 더 필요한데, 혹시 찾으신 것 있으면 알려주세요. 이제 Kawari 8 모듈은 거의 다…

2006.08
22

[App 개발] 마유라 는 한글이 잘 되는군요. ^^

InputStreamReader 의 속성을 SJIS 에서 EUC-KR 로 바꾸는 방법으로 미와 고스트는 안되는데 마유라 고스트는 잘 되는군요. 인텔 맥에서도 문제없이 돌아가고 있습니다. 영환님도 이미 컴파일 해보셨겠지만, 안되었으면 한 번 …

2006.08
22

[App 개발] 니세링고 한글 입력

자바의 BufferedReader 메쏘드를 이용해서 딕셔너리를 읽어들이는 것으로 생각이 되는데 그래서 BufferedReader 를 생성할 때 만드는 InputStreamReader 에 코드를 SJIS 에서 EUC-KR 이나 MS949 로 변경해…

2006.08
21

[App 개발] 나니카 실행 성공

설명에 나온 그대로였어요. 영환님. ㅎㅎ 그런데, 되는 고스트가 있고 안 되는 고스트가 있네... -_-;

2006.08
11

[App 개발] MallocDebug

Xcode 와 CHUD 를 설치하면 여러 가지 Performance Tools 를 보게 됩니다. 그 중에서 Shark 툴을 가장 빈번히 사용하게 되는데요, 이것은 일종의 profiling tool 입니다. 어떤 프로그램이 어떤 경로로 어떤 루틴을 수행…

2006.05
24

[App 개발] OpenGL 을 이용한 게임 만들기 (2) - 3D 모델

드디어 3D 의 세계로 입성하게 되었습니다. 게임 프로그래밍을 생각하시는 많은 분들이 일단 OpenGL 책부터 끄적끄적 하다가 그냥 덮게 되는것은, 어디서부터 손을 대어야 할지 모르기 때문이 아닐까 생각합니다. 일단 OpenGL 을 사용하기 위해서 습…

2006.05
18

[App 개발] OpenGL 을 이용한 게임 만들기 (1) - 2D 맵

앞으로 얼마나 진도를 나갈 수 있을지 저도 장담할 수 없는 시리즈의 첫 번째 편을 쓰게 됩니다. ㅡㅡ; Mac OS X 뿐만 아니라 여러 다양한 플랫폼에서 산업 표준으로 이용되고 있는 OpenGL 을 이용한 게임 제작이 한창입니다. MS 의 Di…

2006.03
23

[App 개발] GNU Scientific Library 를 Xcode 에서 컴파일하다

과학, 공학 전공하시는 분들이시라면, 선호하는 계산 라이브러리가 있으실 줄 압니다. 가장 간편하고 인기있는 라이브러리는 역시 Numerical Recipes 라이브러리가 되겠지만, 요즘은 GNU Scientific Library (GSL) 이 대세죠 …

2006.03
11

[App 개발] 인텔맥에 대처하는 우리의 자세 ㅡㅡ;

이미 작년 6월 이후부터 꾸준하게 유니버설 바이너리 관련 개발자 정보들이 나왔기 때문에 지금은 그 충격이 거의 상쇄되어 버린 기분입니다. 그리고 새로 출시된 인텔 아이맥과 맥북 프로의 성능이 기존 제품을 훨씬 능가한다는 사실을 보면서 많은 개발자들이 …