[c] 계산량이 많은 경우 Fortran을 C보다 최적화하는 것이 더 쉬운가요?

때때로 나는 포트란이 무거운 계산의 경우 C보다 빠르거나 빠를 수 있다고 읽었습니다. 정말 맞습니까? 나는 Fortran을 거의 알지 못한다는 것을 인정해야하지만, 지금까지 본 Fortran 코드에는 언어에 C에없는 기능이 있음을 보여주지 않았습니다.

사실이라면 그 이유를 알려주십시오. 숫자 크 런칭에 적합한 언어 나 라이브러리가 무엇인지 말하지 말고, 앱이나 라이브러리를 작성하지는 않습니다. 궁금합니다.



답변

언어에는 비슷한 기능 세트가 있습니다. 성능 차이는 EQUIVALENCE 문을 사용하지 않는 한 포트란이 앨리어싱이 허용되지 않는다는 사실에서 비롯됩니다. 앨리어싱이있는 코드는 유효하지 않지만 Fortran은 아니지만 프로그래머가이 오류를 감지합니다. 따라서 포트란 컴파일러는 가능한 메모리 포인터의 앨리어싱을 무시하고보다 효율적인 코드를 생성 할 수 있습니다. C의이 작은 예를 살펴보십시오.

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

이 기능은 최적화 후 Fortran 기능보다 느리게 실행됩니다. 왜 그래? 출력 배열에 값을 쓰면 행렬 값을 변경할 수 있습니다. 결국, 포인터는 겹쳐 져서 동일한 메모리 덩어리 ( int포인터 포함 )를 가리킬 수 있습니다. C 컴파일러는 모든 계산을 위해 메모리에서 4 개의 행렬 값을 다시로드해야합니다.

Fortran에서 컴파일러는 매트릭스 값을 한 번로드하여 레지스터에 저장할 수 있습니다. Fortran 컴파일러는 포인터 / 배열이 메모리에서 겹치지 않는다고 가정하기 때문에 그렇게 할 수 있습니다.

다행히도이 restrict문제를 해결하기 위해 키워드 및 엄격 앨리어싱이 C99 표준에 도입되었습니다. 요즘 대부분의 C ++ 컴파일러에서도 잘 지원됩니다. 키워드를 사용하면 프로그래머가 포인터가 다른 포인터와 별명을 지정하지 않는다고 약속하는 힌트를 컴파일러에 제공 할 수 있습니다. 엄격한 앨리어싱 수단 프로그래머 약속 서로 다른 유형의 포인터 엔 절대 오버랩 예 A에 대한 double*의지하지 오버랩을 갖는 int*(즉, 특정의 예외 char*void*아무것도 겹칠 수있다).

당신이 그들을 사용하면 C와 포트란에서 같은 속도를 얻을 것이다. 그러나 restrict키워드를 성능에 중요한 기능으로 만 사용할 수 있다는 것은 C (및 C ++) 프로그램이 훨씬 안전하고 작성하기 쉽다는 것을 의미합니다. 예를 들어, CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)대부분의 Fortran 컴파일러는 경고없이 즐겁게 컴파일하지만 일부 컴파일러, 일부 하드웨어 및 일부 최적화 옵션에만 표시되는 버그를 유발 하는 잘못된 Fortran 코드 :를 고려하십시오 .


답변

네, 1980 년에; 2008 년에? 의존하다

전문적으로 프로그래밍을 시작했을 때, 포트란의 속도 우위는 도전이되었습니다. Dobbs 박사에서 그것에 대해 읽은 것을 기억 하고 나이든 프로그래머들에게 기사에 대해 이야기했습니다.

이론과 실용에 대한 두 가지 견해가 있습니다. 이론상 Fortran은 오늘날 C / C ++ 또는 어셈블리 코드를 허용하는 모든 언어에 본질적인 이점이 없습니다. 실제로 오늘날 포트란은 여전히 ​​수치 코드 최적화를 기반으로하는 역사와 문화의 유산의 이점을 여전히 누리고 있습니다.

Fortran 77까지는 언어 디자인 고려 사항이 최적화에 중점을 두었습니다. 컴파일러 이론과 기술의 상태로 인해 컴파일러 최적화에 코드를 최적화하기 위해 기능과 기능을 제한하는 경우가 종종 있었습니다. Fortran 77을 속도를 위해 기능을 희생시키는 전문 경주 용 자동차라고 생각하는 것이 좋습니다. 요즘 컴파일러는 모든 언어에서 더 좋아졌으며 프로그래머 생산성을위한 기능이 더 중요합니다. 그러나 과학 컴퓨팅에서 사람들이 주로 속도에 관심을 갖는 곳이 여전히 있습니다. 이 사람들은 아마도 포트란 프로그래머였던 사람들로부터 코드, 훈련 및 문화를 물려 받았을 것입니다.

코드 최적화에 관해 이야기하기 시작할 때 많은 문제가 있으며, 이것을 느끼는 가장 좋은 방법 은 빠른 숫자 코드를 가진 사람들이있는 곳 을 찾는 것입니다 . 그러나 매우 중요하게 민감한 코드는 일반적으로 전체 코드 라인의 일부에 불과하고 매우 전문화되어 있습니다. 많은 포트란 코드는 다른 언어의 다른 코드와 마찬가지로 “비효율적”이며 최적화도 그러한 코드의 주요 관심사 .

포트란의 역사와 문화에 대해 배우기 시작하는 가장 좋은 곳은 위키피디아입니다. Fortran Wikipedia 항목 은 훌륭하며 Fortran 커뮤니티에 가치를 만들기 위해 시간과 노력을 기울인 사람들에게 대단히 감사합니다.

(이 답변의 단축 버전은 Nils가 시작한 우수한 스레드에 대한 주석 이었을 것입니다. 그러나 나는 그것을 할 카르마가 없습니다. 실제로, 아마도이 스레드가 실제로는 아무것도 작성하지 않았을 것입니다. 이 주제에 대한 나의 주요 경험 인 화염 전쟁과 언어 편견과는 반대로 정보 내용과 공유 나는 압도되어 사랑을 공유해야했다.)


답변

Fortran은 어느 정도 컴파일러 최적화를 염두에두고 설계되었습니다. 이 언어는 컴파일러가 병렬 처리 (특히 멀티 코어 프로세서)를 활용할 수있는 전체 배열 작업을 지원합니다. 예를 들어

고밀도 행렬 곱셈은 다음과 같습니다.

matmul(a,b)

벡터 x의 L2 규범은 다음과 같습니다.

sqrt(sum(x**2))

또한 FORALL, PURE& ELEMENTAL프로 시저 등과 같은 명령문 은 코드를 최적화하는 데 도움이됩니다. Fortran의 포인터 조차도이 간단한 이유 때문에 C만큼 유연하지 않습니다.

다가오는 Fortran 표준 (2008)에는 병렬 코드를 쉽게 작성할 수있는 공동 배열이 있습니다. CRAY의 G95 (오픈 소스) 및 컴파일러는 이미이를 지원합니다.

따라서 컴파일러는 C / C ++보다 더 잘 최적화 / 병렬화 할 수 있기 때문에 포트란이 빠릅니다. 그러나 인생의 다른 모든 것들과 마찬가지로 좋은 컴파일러와 나쁜 컴파일러가 있습니다.


답변

언어를 모르는 것에 대한 많은 답변이 여기에 있습니다. 이는 FORTRAN 77 코드를 열고 오래된 취약점을 논의한 C / C ++ 프로그래머에게 특히 해당됩니다.

속도 문제는 대부분 C / C ++와 Fortran 사이의 문제라고 생각합니다. 거대한 코드에서는 항상 프로그래머에 따라 다릅니다. 포트란이 능가하는 언어의 일부 기능과 C가하는 일부 기능이 있습니다. 따라서 2011 년에는 어느 쪽이 더 빠른지 아무도 말할 수 없습니다.

현재 언어 자체에 대해 Fortran은 현재 전체 OOP 기능을 지원하며 이전 버전과 완전히 호환됩니다. Fortran 2003을 철저히 사용했으며 사용하기가 기뻤습니다. 일부 측면에서 Fortran 2003은 여전히 ​​C ++ 뒤에 있지만 사용법을 살펴 보겠습니다. 포트란은 주로 Numerical Computation에 사용되며 속도 때문에 멋진 C ++ OOP 기능을 사용하는 사람은 없습니다. 고성능 컴퓨팅에서 C ++은 갈 곳이 거의 없습니다 (MPI 표준을 살펴보면 C ++이 더 이상 사용되지 않음을 알 수 있습니다!).

요즘에는 포트란과 C / C ++로 간단히 혼합 언어 프로그래밍을 할 수 있습니다. 포트란에는 GTK +를위한 인터페이스도 있습니다. 무료 컴파일러 (gfortran, g95)와 많은 훌륭한 상용 컴파일러가 있습니다.


답변

포트란이 더 빠를 수있는 몇 가지 이유가 있습니다. 그러나 중요한 양은 중요하지 않거나 어쨌든 해결 될 수 있으므로 중요하지 않습니다. 요즘 Fortran을 사용하는 주된 이유는 레거시 응용 프로그램을 유지 관리하거나 확장하기 때문입니다.

  • 함수에 대한 순수 및 요소 키워드. 부작용이없는 기능입니다. 이는 컴파일러가 동일한 함수가 동일한 값으로 호출 될 것이라는 것을 알고있는 특정 경우 최적화를 허용합니다. 참고 : GCC는 언어의 확장으로 “순수”를 구현합니다. 다른 컴파일러도 가능합니다. 모듈 간 분석도이 최적화를 수행 할 수 있지만 어렵습니다.

  • 개별 요소가 아닌 배열을 다루는 표준 함수 세트. sin (), log (), sqrt ()와 같은 것은 스칼라 대신 배열을 취합니다. 이를 통해 루틴을보다 쉽게 ​​최적화 할 수 있습니다. 자동 벡터화는 대부분의 경우 이러한 기능이 인라인 또는 내장 인 경우 동일한 이점을 제공합니다.

  • 내장 복합 유형. 이론적으로 이것은 컴파일러가 특정 경우에 특정 명령어를 재정렬하거나 제거 할 수 있지만 struct {double re, im; }; C에서 사용되는 관용구. 운영자가 포트란에서 복잡한 유형에 대해 작업하지만 개발 속도가 빨라집니다.


답변

Fortran에 유리한 점은 벡터 및 배열 기반 수학을 표현하는 데 약간 더 적합한 언어라는 것입니다. 휴대용 코드는 실제로 컴파일러에게 무언가를 말할 수 있다고 가정 할 수 없기 때문에 위에서 지적한 포인터 분석 문제는 실제로 실제입니다. 도메인이 어떻게 보이는지에 더 가까운 방식으로 표현 컴퓨터에 대한 이점이 항상 있습니다. C는 실제로 배열을 가지고 있지 않습니다. 자세히 보면, 일종의 행동 만 할 수 있습니다. 포트란은 진짜 소란 스러웠습니다. 특정 유형의 알고리즘, 특히 병렬 시스템에 대해 더 쉽게 컴파일 할 수 있습니다.

런타임 시스템 및 호출 규칙과 같이 C와 현대 Fortran은 차이가 나는 것이 무엇인지 알기에는 충분히 유사합니다. 여기서 C는 실제로 기본 C입니다. C ++은 매우 다른 성능 특성을 가진 완전히 다른 문제입니다.


답변

한 언어가 다른 언어보다 빠르다는 것은 없으므로 정답은 ‘ 아니요’ 입니다.

실제로 물어봐야 할 것은 “Fortran 컴파일러 X로 컴파일 된 코드가 C 컴파일러 Y로 컴파일 된 동등한 코드보다 빠릅니까?”입니다. 물론이 질문에 대한 대답은 어떤 두 컴파일러를 선택 하느냐에 달려 있습니다.

또 다른 질문은 “컴파일러를 최적화하는 데 같은 노력을 기울이면 어느 컴파일러가 더 빠른 코드를 생성 할 수 있을까요?” 이에 대한 대답은 실제로 포트란 입니다. 포트란 컴파일러에는 다음과 같은 장점이 있습니다.

  • Fortran은 일부 사람들이 컴파일러를 사용하지 않겠다고 약속 한 날 어셈블리와 경쟁해야했기 때문에 속도를 높이기 위해 설계되었습니다. C는 유연하게 설계되었습니다.
  • Fortran의 틈새 시장은 숫자 위기였습니다. 이 도메인 코드는 결코 빠르지 않습니다. 따라서 언어를 효율적으로 유지해야한다는 압박이 항상 컸습니다.
  • 컴파일러 최적화에 대한 대부분의 연구는 Fortran 번호 크 런칭 코드의 속도를 높이려는 사람들이 수행하므로 Fortran 코드 최적화는 다른 컴파일 된 언어를 최적화하는 것보다 훨씬 더 잘 알려진 문제이며, Fortran 컴파일러에서 새로운 혁신이 먼저 나타납니다.
  • Biggie : C는 Fortran보다 더 많은 포인터 사용을 권장합니다. 이로 인해 C 프로그램에서 모든 데이터 항목의 잠재적 인 범위가 크게 증가하여 최적화하기가 훨씬 어려워집니다. Ada는이 영역에서 C보다 훨씬 우수하며 일반적으로 사용되는 Fortran77보다 훨씬 현대적인 OO 언어입니다. C보다 빠른 코드를 생성 할 수있는 OO 언어를 원한다면 이것이 옵션입니다.
  • Fortran 컴파일러의 고객은 수의 틈새 시장으로 인해 C 컴파일러의 고객보다 최적화에 더 관심을 갖는 경향이 있습니다.

그러나 누군가 C 컴파일러의 최적화에 많은 노력을 기울이지 않고 플랫폼의 Fortran 컴파일러보다 더 나은 코드를 생성하는 것을 막을 수는 없습니다. 실제로, C 컴파일러가 생성 한 판매량이 많을수록이 시나리오를 실현할 수 있습니다.