C로 다차원 배열을 매개변수로 받는 함수 작성에 관해
글쓴이: k333ps / 작성시간: 일, 2012/01/22 - 4:31오후
안녕하세요.
항상 포트란으로 수치해석을 해왔었는데, C로 새롭게 작성하려고 합니다.
포트란의 서브루틴과 달리 C의 함수는 Call by reference 형식이라
배열 자체를 함수의 매개변수로 쓰기 위해선 약간의 꼼수(포인터 or 구조체)를
써야한다고 알고 있습니다. 포인터를 써서 함수 밖의 배열을 함수 내에서 처리하는
것에 대해선 어느정도 이해가 되었는데요, 구조체를 써서(이 방법이 권장되더군요)
함수 밖의 다차원 배열을 함수 안에서 자유롭게 처리하는 방법에 대해 간단하게나마
설명해주실수 있나요?
Forums:
어자피 C/C++ 을 쓰실 거라면
이전에 포트란에서 했던 방식은 버리셔야...
포트란 orient면 꼼수겠지만 C orient 면 그게 정석이겠죠.
우선 구조체를 넘기는 건... 함수가 불릴 때 구조체 멤버에 대한 복사가 일어나기 때문에 성능상 안좋고
C++ 이라면 & 레퍼런스를 넘기든지, C 라면 포인터 정도를 넘기면 별 문제 없겠네요.
구조체를 넘기는 방식이 잘 이해가 안되는데요...
간단하게나마 설명해 주시면 감사하겠습니다.
또, 포인터를 넘기는 경우에 말인데요. 크기가 NX*NY*NZ 3차원 배열을 넘긴다고 가정할때
외부 배열을 함수 내부에서 자유롭게 다루기 위해서는
void function(double matrix[],nx,ny,nz)
{
double *new_matrix[nx][ny][nz] = *matrix;
}
이런식으로 함수안에서 새로운 배열을 생성해서 외부배열을 할당해 주면 되나요?
배열을 다루시려면 C에서는 다차원 배열이 사실은 없습니다
아니, 그렇게 생각하고 계시는게 편하고요.
여러가지로 할수 있지만 만약 nx, ny, nz 등 가변 사이즈의 3차원 배열을 다룬다면
void function(double matrix[],nx,ny,nz)
{
matrix[NY*NZ*nx + NZ*ny + nz] = 3.141592;
}
정도로도 되겠지만 곱셈 연산이 있으니 성능상 괘 안좋은 코드가 나올수도 있겠네요.
원하시는 성능을 위해서는 많은 튜닝이 요구될 겁니다.
numerical recipe를 보시면 참고가 되실 겁니다.
감사합니다!
뉴메리컬 레시피도 읽어봐야겠네요.
감사합니다!
뉴메리컬 레시피도 읽어봐야겠네요.
c 를 사용하시려는 이유를 모르겠지만...
많이 사용된다고 해서 프로그래밍하기에 좋은 언어는 아닙니다. 특히 운영체제 개발 및 그와 관련된 프로그램 개발같은 저수준 제어와 관련된 프로그램이 아닌 이상, 수치해석과 같은 계산위주의 프로그램개발에서 c 를 사용할만한 이유를 모르겠습니다. 속도때문이라면 포트란이 C 와 비슷하거나 오히려 더 빠른경우가 많습니다.
요새는 C컴파일러도 좋아져서 쓸만하다고 합니다.
요새는 C컴파일러도 좋아져서 쓸만하다고 합니다.
유명한 과학계산용 라이브러리인 GSL은 C/C++로 제공됩니다.
http://www.gnu.org/software/gsl/
심지어 전산유체역학에 C++쓰는 그룹도 있는걸요.
http://www.openfoam.com/
피할 수 있을때 즐겨라! http://melotopia.net/b
C를 사용하려는 이유.
네 물론 수치해석에 한해서는 포트란이 C보다 여러모로 유리한 점이 많다는 건 알고 있었습니다.
하지만 계산시간이 길어 좀 불편해서 이번에 새로 짜면서 GPGPU를 적용해 보려고 하거든요...
OpenCL이나 CUDA로 계산하려면 일단 C로 짜놓는게 좋지 않나 싶어서 C로 짤까 생각중입니만 어떻게 생각하시는지요?
여러가지 구현 방법이 있겠습니다만, 일반적인
여러가지 구현 방법이 있겠습니다만, 일반적인 C프로그래밍의 경우에는 (C99를 지원하는 컴파일러를 사용한다는 전제하에) 가변 배열을 사용하고 배열의 크기를 파라메터로 넘겨주면 편리하더군요.
OpenCL로 처리할 때는 전형적인 데이터 병렬 처리가 되겠는데, 이 경우 먼저 처리해야 할 데이터를 어떻게 분할할 지 정합니다.
보통 멀티코어 CPU나, GPU의 프로세싱 유닛수를 미리 파악해서 그 숫자의 정수배로 분할하는 게 성능상 좋습니다만, 꼭 그렇게 하지 않더라도 하위 레이어에서 적당히 작업을 할당해 줍니다.
위의 경우, matrix를 NX개로 나누어 볼 경우를 생각할 수 있습니다. 나누는 방법도 여러가지가 있지만 OpenCL용어로 global work item이 NX개가 되도록 분할해 볼 수있습니다. 그리고나서 function함수를 OpenCL커널 함수로 작성하여야 하는데, 커널 함수의 시작부분에 자기자신의 global work item 인덱스를 알아내어야 합니다. global work item의 인덱스를 gwi라고 하면 그 다음은 커널이 matrix[gwi][0][0] ~ matrix[gwi][NY][NZ]부분의 처리를 담당하면 되겠습니다.
생산적인 댓글을 달자
감사합니다!
많은 도움이 되었어요.
댓글 달기