문제

이 '단순화'포트란 코드가 있습니다

real B(100, 200) 
real A(100,200)

... initialize B array code.

do I = 1, 100
  do J = 1, 200
    A(J,I) = B(J,I)
  end do
end do

프로그래밍 전문가 중 하나는 Fortran이 칼럼 순서로 데이터에 효율적으로 액세스하는 반면 C는 데이터에 효율적으로 액세스 할 수 있다고 경고했습니다. 그는 코드를 잘 살펴보고 구식 프로그램의 속도를 유지하기 위해 루프를 전환 할 준비를했습니다.

내가있는 게으른 프로그래머이기 때문에, 관련된 노력의 시대와 내가 할 수있는 실수를 인식하면서, 나는이 코드를 안전하고 쉽게 변환 할 수있는 #define 기술이 있는지 궁금해하기 시작했습니다.

의견 있으십니까?

도움이 되었습니까?

해결책

C에서 다차원 배열은 다음과 같이 작동합니다.

#define array_length(a) (sizeof(a)/sizeof((a)[0]))
float a[100][200];
a[x][y] == ((float *)a)[array_length(a[0])*x + y];

다시 말해, 그들은 정말 평평한 배열과입니다 [][] 단지 구문 설탕입니다.

당신이 이것을한다고 가정합니다 :

#define at(a, i, j) ((typeof(**(a)) *)a)[(i) + array_length((a)[0])*(j)]
float a[100][200];
float b[100][200];
for (i = 0; i < 100; i++)
    for (j = 0; j < 200; j++)
        at(a, j, i) = at(b, j, i);

당신은 기억을 통해 순차적으로 걷는 것입니다 a 그리고 b 실제로 열 순서로 배치됩니다. 그것은 그것에 끔찍합니다 a[x][y] != at(a, x, y) != a[y][x], 그러나 당신이 이렇게 속임수를 기억하는 한, 당신은 괜찮을 것입니다.

편집하다

남자, 멍청한 느낌. 이 정의의 의도는 만드는 것입니다 at(a, x, y) == at[y][x], 그리고 그것은 그렇습니다. 따라서 훨씬 간단하고 이해하기 쉽습니다

#define at(a, i, j) (a)[j][i]

내가 위에서 제안한 것이 더 낫습니다.

다른 팁

당신의 Fortran 사람들이 올바르게했다고 확신합니까?

원래 게시 한 코드 스 니펫은 이미 배열에 Row-Major 순서로 배열에 액세스하고 있습니다 (Fortran의 경우 '비효율적 인', '효율적').

코드 스 니펫과 질문에서 언급 한 바와 같이,이 '올바른'을 얻는 것은 오류가 발생할 수 있습니다. 이와 같은 세부 사항에 대해 걱정하지 않고 Fortran 코드를 C로 포팅하는 것에 대해 걱정하십시오. 포트가 작동하는 경우-열 주문형 액세스가 행 주문 액세스에 대한 열표 액세스를 변경하는 것에 대해 걱정할 수 있습니다 (포트가 작동 한 후에도 실제로 중요하다면).

대학 밖에서 첫 번째 프로그래밍 작업 중 하나는 Fortran에서 포팅 된 장기 C 앱을 수정하는 것이 었습니다. 배열은 당신보다 훨씬 컸으며 달리기 당 약 27 시간이 걸렸습니다. 그것을 고치고 나면 그들은 약 2.5 시간 안에 달렸다 ... 꽤 달콤한!

(좋아요, 실제로 할당되지 않았지만 호기심이 많았고 코드에 큰 문제가 발견되었습니다. 일부 오래된 타이머 중 일부는이 수정에도 불구하고 나를 좋아하지 않았습니다.)

동일한 문제가 여기에있는 것 같습니다.

real B(100, 200) 
real A(100,200)

... initialize B array code.

do I = 1, 100
  do J = 1, 200
    A(I,J) = B(I,J)
  end do
end do

당신의 반복 (좋은 fortran)은 다음과 같습니다.

real B(100, 200) 
real A(100,200)

... initialize B array code.

do J = 1, 200
  do I = 1, 100
    A(I,J) = B(I,J)
  end do
end do

그렇지 않으면 당신은 Row-Major의 배열을 통해 행진하고 있습니다. 이는 매우 비효율적 일 수 있습니다.

적어도 나는 그것이 그것이 Fortran에있는 방법이라고 믿습니다. 오랜 시간이 걸렸습니다.


코드를 업데이트 한 것을 보았습니다 ...

이제 루프 제어 변수를 교체하여 행을 반복 한 다음 C로 변환하는 경우 열에 반복 내부를 반복 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top