C로 다차원 배열을 매개변수로 받는 함수 작성에 관해

k333ps의 이미지

안녕하세요.

항상 포트란으로 수치해석을 해왔었는데, C로 새롭게 작성하려고 합니다.

포트란의 서브루틴과 달리 C의 함수는 Call by reference 형식이라

배열 자체를 함수의 매개변수로 쓰기 위해선 약간의 꼼수(포인터 or 구조체)를

써야한다고 알고 있습니다. 포인터를 써서 함수 밖의 배열을 함수 내에서 처리하는

것에 대해선 어느정도 이해가 되었는데요, 구조체를 써서(이 방법이 권장되더군요)

함수 밖의 다차원 배열을 함수 안에서 자유롭게 처리하는 방법에 대해 간단하게나마

설명해주실수 있나요?

라스코니의 이미지

이전에 포트란에서 했던 방식은 버리셔야...
포트란 orient면 꼼수겠지만 C orient 면 그게 정석이겠죠.

우선 구조체를 넘기는 건... 함수가 불릴 때 구조체 멤버에 대한 복사가 일어나기 때문에 성능상 안좋고
C++ 이라면 & 레퍼런스를 넘기든지, C 라면 포인터 정도를 넘기면 별 문제 없겠네요.

k333ps의 이미지

간단하게나마 설명해 주시면 감사하겠습니다.

또, 포인터를 넘기는 경우에 말인데요. 크기가 NX*NY*NZ 3차원 배열을 넘긴다고 가정할때

외부 배열을 함수 내부에서 자유롭게 다루기 위해서는

void function(double matrix[],nx,ny,nz)
{
double *new_matrix[nx][ny][nz] = *matrix;
}

이런식으로 함수안에서 새로운 배열을 생성해서 외부배열을 할당해 주면 되나요?

라스코니의 이미지

아니, 그렇게 생각하고 계시는게 편하고요.

여러가지로 할수 있지만 만약 nx, ny, nz 등 가변 사이즈의 3차원 배열을 다룬다면

void function(double matrix[],nx,ny,nz)
{
matrix[NY*NZ*nx + NZ*ny + nz] = 3.141592;
}

정도로도 되겠지만 곱셈 연산이 있으니 성능상 괘 안좋은 코드가 나올수도 있겠네요.
원하시는 성능을 위해서는 많은 튜닝이 요구될 겁니다.

numerical recipe를 보시면 참고가 되실 겁니다.

k333ps의 이미지

뉴메리컬 레시피도 읽어봐야겠네요.

k333ps의 이미지

뉴메리컬 레시피도 읽어봐야겠네요.

익명 사용자의 이미지

많이 사용된다고 해서 프로그래밍하기에 좋은 언어는 아닙니다. 특히 운영체제 개발 및 그와 관련된 프로그램 개발같은 저수준 제어와 관련된 프로그램이 아닌 이상, 수치해석과 같은 계산위주의 프로그램개발에서 c 를 사용할만한 이유를 모르겠습니다. 속도때문이라면 포트란이 C 와 비슷하거나 오히려 더 빠른경우가 많습니다.

snowall의 이미지

요새는 C컴파일러도 좋아져서 쓸만하다고 합니다.

유명한 과학계산용 라이브러리인 GSL은 C/C++로 제공됩니다.
http://www.gnu.org/software/gsl/

심지어 전산유체역학에 C++쓰는 그룹도 있는걸요.

http://www.openfoam.com/

피할 수 있을때 즐겨라! http://melotopia.net/b

k333ps의 이미지

네 물론 수치해석에 한해서는 포트란이 C보다 여러모로 유리한 점이 많다는 건 알고 있었습니다.

하지만 계산시간이 길어 좀 불편해서 이번에 새로 짜면서 GPGPU를 적용해 보려고 하거든요...

OpenCL이나 CUDA로 계산하려면 일단 C로 짜놓는게 좋지 않나 싶어서 C로 짤까 생각중입니만 어떻게 생각하시는지요?

sohn9086의 이미지

여러가지 구현 방법이 있겠습니다만, 일반적인 C프로그래밍의 경우에는 (C99를 지원하는 컴파일러를 사용한다는 전제하에) 가변 배열을 사용하고 배열의 크기를 파라메터로 넘겨주면 편리하더군요.

void function(int NX, int NY, int NZ, double matrix[NX][NY][NZ]) /* 파라메터 순서가 바뀌면 안됨 */
{
  int x, y, z;
 
  for (x = 0; x < NX; x++)
    for (y = 0; y < NY; y++)
      for (z = 0; z < NZ; z++)
        matrix[x][y][x] *= 0.1;
        /* ... etc */
}

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]부분의 처리를 담당하면 되겠습니다.

생산적인 댓글을 달자

k333ps의 이미지

많은 도움이 되었어요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.