현대 시대의 포트란 배우기


80

저는 최근에 많은 양의 과학적 계산 집약적 인 FORTRAN 코드를 유지하기 위해 왔습니다. Google과 두 권의 입문 레벨 책에도 불구하고 40 년 된 언어의 모든 뉘앙스를 다루는 데 어려움을 겪고 있습니다. 이 코드는 "성능 향상 개선"으로 가득 차 있습니다. 사람이 어떤 가이드 또는에 대한 실질적인 조언이 있습니까 CS (101) 수준에 -optimizing FORTRAN을? FORTRAN 코드 최적화가 어떻게 작동하는지 아는 사람이 있습니까? FORTRAN 77/90 코드베이스를 인수하는 Java / C ++ /. NET 개발자에게 발생하지 않을 수있는 일반적인 FORTRAN 'gotchas'가 있습니까?


4
이 텍스트가 흥미로울까요? fortranrefactoring.com.ar/papers/…
Rook

2
@DavidSokol 저는 공룡 TDL 팟 캐스트 에서 여러분의 말을 재미있게 들었습니다 . 특히 문맥에 대한이 질문을 들었습니다 .
Tim Post

2
위의 링크는 죽었고 문서는 여기에 있습니다 : fortranrefactoring.org/papers/…

답변:


89

프로그래머가 과거에했던 일에 대해 "느낌"을 가져야합니다. 내가 작업하는 대부분의 코드는 나보다 오래되었고 부모님이 고등학교에 다닐 때 "새로운"기계에서 실행되었습니다.

내가 다루는 일반적인 FORTRAN-ism은 가독성을 떨어 뜨립니다.

  • 공통 블록
  • 암시 적 변수
  • 공유 CONTINUE 문이있는 두 개 또는 세 개의 DO 루프
  • DO 루프 대신 GOTO
  • 산술 IF 문
  • 계산 된 GOTO
  • 일부 공통 블록에서 등가 REAL / INTEGER / other

이를 해결하기위한 전략에는 다음이 포함됩니다.

  1. 얻을 Spag / plusFORT을 , 가치가 돈, 그것은 자동으로 많이 해결하고 버그 무료 (TM)
  2. 가능하면 Fortran 90으로 이동하고, 자유 형식 Fortran 77로 이동하지 않으면
  3. 각 서브 루틴에 IMPLICIT NONE을 추가 한 다음 모든 컴파일 오류를 수정하고 시간이 많이 걸리지 만 궁극적으로 필요한 경우 일부 프로그램이 자동으로이를 수행 할 수 있습니다 (또는 스크립트를 작성할 수 있음).
  4. 모든 COMMON 블록을 MODULE, 낮은 매달려있는 과일로 이동
  5. 산술 IF 문을 IF..ELSEIF..ELSE 블록으로 변환
  6. 계산 된 GOTO를 SELECT CASE 블록으로 변환
  7. 모든 DO 루프를 최신 F90 구문으로 변환

    myloop: do ii = 1, nloops
        ! do something
    enddo myloop
    
  8. 동등한 공통 블록 멤버를 모듈에 할당 된 ALLOCATABLE 메모리로 변환하거나 Hollerith가 REAL에 저장되는 경우 해당 문자 루틴으로 변환합니다.

가독성 작업을 수행하는 방법에 대해 더 구체적인 질문이 있으면 조언을 드릴 수 있습니다. 40 년에 걸쳐 작성된 몇 십만 줄의 Fortran 코드베이스를 가지고 있으며,이 코드는 내가 어떤 식 으로든 책임을지고 있기 때문에 발견 할 수있는 "문제"를 발견했을 것입니다.


3
또한 포트란 리팩토링에 관한 멋진 텍스트입니다. fortranrefactoring.com.ar/papers/…
Rook

코드가 잘 구성되어 있지 않고 최적화 세부 사항에 의해 상당히 난독 화되어 있다면 매우 어렵습니다. 포트란 90 스타일로 마이그레이션하면 도움이 될 것입니다. 또한 최신 버전의 fortran 2008은 최적화 기능을 제공합니다.
Zeus

plusFORT 사이트가 여기로 이동 한 것 같습니다 : polyhedron.com/?product=plusfort
jrh

32

레거시 Fortran Soapbox

나는 꽤 오랫동안 레거시 Fortran 코드 기반을 유지 / 개선하는 데 도움을 줬고 대부분의 경우 sixlettervariables 가 돈에 있다고 생각 했습니다 . 그러나 그 조언은 기술적 인 경향이 있습니다. 더 어려운 행은 "우수 사례"를 구현하는 것입니다.

  • 필요한 코딩 스타일 및 코딩 지침을 설정합니다.
  • 코드베이스에 제출 된 모든 항목에 대해 코드 검토 (코더 이상의 것!)를 요구합니다. (버전 제어는이 프로세스와 연결되어야합니다.)
  • 단위 테스트 빌드 및 실행을 시작하십시오. 벤치 마크 또는 회귀 테스트도 마찬가지입니다.

요즘은 당연한 일처럼 들릴지 모르지만 과도하게 일반화 될 위험이 있지만 대부분의 포트란 코드 상점에는 확고한 문화가 있으며 일부는 "소프트웨어 엔지니어링"이라는 용어가 존재하기 전에 시작되었으며 시간이 지남에 따라 지배하게 될 것이라고 주장합니다. "지금 완료"입니다. (이것은 Fortran 상점에만 국한되지 않습니다.)

Gotchas 수용

하지만 이미 존재하는 끔찍한 오래된 레거시 코드베이스로 무엇을해야할까요? 나는 다시 작성에 Spolsky 조엘에 동의 하지 않습니다 . 그러나 내 생각에 sixlettervariables 는 허용 가능한 예외를 가리 킵니다. 소프트웨어 도구를 사용하여 더 나은 Fortran 구조로 전환합니다. 코드 분석기 ( FORCHECK ) 및 코드 재 작성기 ( plusFORT ) 는 많은 것을 포착 / 수정할 수 있습니다 . 손으로해야하는 경우 긴급한 이유가 있는지 확인하십시오. (저는 소프트웨어 버그 수정에서 나온 소프트웨어 버그의 수에 대한 언급이 있었으면 좋겠습니다. 겸손합니다. 그러한 통계는 Expert C Programming 에 있다고 생각 합니다.)

아마도 Fortran gotchas 게임에서 승리하는 가장 좋은 공격은 최고의 방어력을 갖는 것입니다. 언어를 상당히 잘 아는 것입니다. 이를 위해 ... 책을 추천합니다!

포트란 데드 트리 라이브러리

나는 수년 동안 "QA nag"로서 약간의 성공을 거두었지만 교육은 때때로 우연히 효과가 있으며 가장 영향력있는 것 중 하나는 누군가가 가지고있는 참고서라는 것을 발견했습니다. 나는 사랑하고 적극 추천합니다

과학자 및 엔지니어를위한 Fortran 90/95 , Stephen J. Chapman

이 책은 사용해서는 안되는 구조를 구체적으로 식별하고 더 나은 대안을 제공한다는 점에서 Fortran 77 과도 잘 어울립니다. 그러나 실제로는 교과서이며 Fortran 95의 핵심을 알고 싶을 때 증기가 떨어질 수 있습니다.

Fortran 90/95 Explained , by Michael Metcalf & John K. Reid

Fortran 95에 대한 참조 (원문)로. 가장 명쾌한 글은 아니지만 새로운 Fortran 95 기능을 최대한 활용하고 싶을 때 베일이 해제됩니다.

Fortran 77에서 Fortran 90으로 이동하는 문제에 초점을 맞춰

Fortran 90으로 마이그레이션 , Jim Kerrigan

그러나 책은 이제 절판되었습니다. (저는 O'Reilly의 Safari 사용을 이해하지 못합니다 . 왜 절판 된 책을 모두 사용할 수 없습니까?)

마지막으로, 훌륭한, 멋진 클래식,에 후계자에 관한 소프트웨어 도구 , 나는 지명

Michael Kupferschmid의 클래식 포트란

이 책은 "오직"Fortran 77으로 무엇을 할 수 있는지 보여줄뿐만 아니라 발생하는 더 미묘한 문제에 대해서도 설명합니다 (예 : EXTERNAL 선언을 사용해야하거나 사용해서는 안 됨). 이 책은 "Software Tools"와 똑같은 공간을 정확히 다루지는 않지만 "fun"이라고 태그를 붙인 세 개의 Fortran 프로그래밍 책 중 두 권입니다 .... ( 여기 세 번째입니다 ).

거의 모든 Fortran 컴파일러에 적용되는 기타 조언

  • IMPLICIT NONE 동작을 적용하는 컴파일러 옵션이 있으며,이를 사용하여 먼저 IMPLICIT NONE 선언으로 수정하지 않고 문제 루틴을 식별 할 수 있습니다. 이 조언은 레거시 루틴에 삽입 된 IMPLICIT NONE 명령으로 인해 처음 빌드 폭탄이 터지기 전까지는 의미가 없어 보입니다. (뭐? 코드 리뷰에서이 문제를 파악하지 못했습니까? ;-)
  • Fortran 77 코드를 디버깅 할 때 유용 할 수있는 배열 경계 검사를위한 컴파일러 옵션이 있습니다.
  • Fortran 90 컴파일러는 거의 모든 Fortran 77 코드와 더 오래된 Fortran 코드를 컴파일 할 수 있어야합니다. Fortran 90 컴파일러에서보고 옵션을 켜고이를 통해 레거시 코드를 실행하면 구문 검사를 제대로 시작할 수 있습니다. 일부 상용 Fortran 77 컴파일러는 실제로 Fortran 77 모드에서 실행되는 Fortran 90 컴파일러이므로 어떤 빌드 스크립트를 사용하든 상대적으로 간단한 옵션이 될 수 있습니다.

1
과학자와 엔지니어를위한 Fortran 90/95 링크는 죽었지 만 아마존 에서 약 50 달러, 페이퍼 백 1 판은 약 $ 25
jrh

24

원래 질문에는 제가주의해야 할 것이 있습니다. 당신은 코드가 "성능 향상 개선"으로 가득 차 있다고 말합니다. Fortran 문제는 일반적으로 과학적, 수학적 특성이므로 컴파일을 개선하기 위해 이러한 성능 트릭이 있다고 가정하지 마십시오. 아마도 언어에 관한 것이 아닙니다. Fortran에서 해결책은 코드 자체의 효율성에 관한 것이 아니라 최종 문제를 해결하기위한 기본 수학입니다. 트릭은 컴파일 속도를 느리게 만들고 논리를 지저분하게 만들 수도 있지만 솔루션을 더 빠르게 만드는 것입니다. 그것이 무엇을하는지, 왜 그런지 정확히 알지 못한다면 그냥 두십시오.

멍청 해 보이는 변수 이름을 변경하는 것과 같은 단순한 리팩토링조차도 큰 함정이 될 수 있습니다. 주어진 과학 분야에서 역사적으로 표준 수학 방정식은 Maxwell 시대 이후로 특정한 속기를 사용했을 것입니다. 따라서 전자기학에서 B (:)라는 배열을보기 위해 모든 Emag 엔지니어에게 정확히 무엇을 해결해야하는지 알려줍니다. 위험에 따라 변경하십시오. 도덕, 이름을 바꾸기 전에 과학의 표준 명명법을 알아 두십시오.


7

FORTRAN (진지하게 사용한 지 오래되었지만 77 가지 맛)과 C / C ++ 모두 경험이있는 사람으로서 즉시 염두에 두는 항목은 배열입니다. FORTRAN 배열은 C / C ++ / Java에서와 같이 0 대신 1의 인덱스로 시작합니다. 또한 메모리 배열이 반대입니다. 따라서 첫 번째 인덱스를 증가 시키면 순차적 인 메모리 위치가 제공됩니다.

제 아내는 여전히 FORTRAN을 정기적으로 사용하고 있으며 제가 그녀를 돕기 시작하려고하는 지금 작업해야하는 C ++ 코드를 가지고 있습니다. 그녀의 개종 중에 문제가 생기면 나는 그것들을 지적하려고 노력할 것입니다. 아마도 그들은 도움이 될 것입니다.


12
Fortran 배열은 기본적으로 인덱스 1로 시작하지만 모든 값으로 시작하도록 선언 할 수 있습니다.
MSB

6

저는 1967 년부터 '66 버전부터 Fortran을 사용해 왔습니다 (32k 단어의 메모리를 가진 IBM 7090에서). 그런 다음 PL / 1을 얼마 동안 사용했지만 나중에 Fortran 95로 돌아가서 우리가 가진 행렬 / 복소수 문제에 이상적으로 적합하기 때문입니다. 이전 코드의 복잡한 구조의 대부분은 사용 가능한 메모리의 양이 적기 때문에 계산되거나 할당 된 GOTOs 를 통해 몇 줄의 코드를 재사용하는 것과 같은 일을 강요한다는 고려 사항을 추가하고 싶습니다 . 또 다른 문제는 반복되는 모든 하위 표현식에 대한 보조 변수를 정의하여 최적화하는 것입니다. 컴파일러는이를 위해 최적화하지 않았습니다. 또한 쓰기가 허용되지 않았습니다 DO i=1,n+1. 당신은 작성해야했다 n1=n+1;DO i=1,n1. 결과적으로 오래된 코드는 불필요한 변수로 가득 차 있습니다. Fortran 95에서 코드를 다시 작성했을 때 변수의 10 % 만 살아 남았습니다. 코드를 더 읽기 쉽게 만들고 싶다면 쉽게 제거 할 수있는 변수를 찾는 것이 좋습니다.

내가 언급 할 수있는 또 다른 점은 수년 동안 복잡한 산술 및 다차원 배열이 매우 비효율적이라는 것입니다. 그렇기 때문에 실제 변수와 단일 선형 인덱스로 처리되는 행렬 만 사용하여 복잡한 계산을 수행하도록 코드를 다시 작성하는 경우가 많습니다.


5

글쎄, 어떤 의미에서 당신은 운이 좋다. 왜냐하면 Fortran은 미묘한 제어 흐름 구조 나 상속 등의 방식을 많이 가지고 있지 않기 때문이다. 다른 한편으로는 산술적으로 계산 된 분기-숫자 레이블 항목, 선언이 필요하지 않은 암시 적으로 형식화 된 변수, 실제 키워드의 부족과 같은 정말 놀라운 문제가 있습니다.

나는 "성능 향상 개선"에 대해 모른다. 수십 년의 컴파일러 기술이 대부분의 힌트를 불필요하게 만들었 기 때문에 대부분은 비효율적이라고 생각합니다. 안타깝게도 대규모 재 작성을 계획하지 않는 한 그대로 두어야 할 것입니다.

어쨌든 핵심 과학 계산 코드는 상당히 읽기 쉬워야합니다. 중위 산술을 사용하는 모든 프로그래밍 언어는 Fortran의 산술 및 할당 코드를 읽기위한 좋은 준비가 될 것입니다.


5

코드를 유지하기 위해해야 ​​할 일을 설명해 주시겠습니까? 정말로 코드를 수정해야합니까? 코드 자체 대신 해당 코드에 대한 인터페이스 만 수정하여 벗어날 수 있다면 그게 최선일 것입니다.

FORTRAN뿐만 아니라 대규모 과학 코드를 다룰 때 내재 된 문제는 기본 수학 및 구현이 모두 복잡하다는 것입니다. 거의 기본적으로 구현 합리적인 시간 내에 실행하기 위해 코드 최적화 포함해야합니다. 이것은이 분야의 많은 코드가 해당 분야의 전문가이지만 소프트웨어 개발이 아닌 과학자 / 엔지니어에 의해 생성된다는 사실로 인해 더욱 복잡해집니다. "이해하기 쉬움"이 그들에게 최우선 순위가 아니라고 말합시다 (저는 그들 중 하나 였지만 여전히 더 나은 소프트웨어 개발자가되는 법을 배우고 있습니다).

문제의 특성상 일반적인 질문과 답변만으로는 도움이되지 않는다고 생각합니다. 코드 조각이 첨부 된 일련의 특정 질문을 게시하는 것이 좋습니다. 아마도 당신에게 가장 두통을주는 것부터 시작 하시겠습니까?


4

나는 FORTRAN을 사랑했고, 그것을 가르치고 코딩하곤했습니다. 그냥 집어 넣고 싶었어요. 몇 년 동안 건드리지 않았어요.
나는 COBOL에서 시작했고, FORTRAN으로 이사했을 때 나는 내가 해방되었다고 느꼈다. 모든 것이 상대적입니다. 나는 위에서 말한 것을 두 번째로 할 것입니다-이것이 절차 적 언어라는 것을 인식하고-하위 요소가 없습니다-그러니 당신이 보는대로 가져 가십시오.
아마 당신이 시작하기를 실망시킬 것입니다.


2
저도 그 단계를 거쳤습니다. 사실 저는 문제를 최소화 한 "모범 사례"를 기억합니다. 하지만 Lisp, Pascal, C, C ++로 넘어갔습니다. 아직 포트란과 함께 작업해야합니다. 진짜 문제는 대부분이 프로그래머 규율이 거의없이 작성되었다는 것입니다. 사람들은 여전히 ​​포트란을 가르치고 있지만 훈육을 가르치지는 않습니다.
Mike Dunlavey

3

나는 펀치 카드로 Fortran IV (WATFIV)를 시작했고, 초기 근무 시절은 VS FORTRAN v1 (IBM, Fortran 77 수준)이었습니다. 이 스레드에는 많은 좋은 조언이 있습니다.

나는 당신이 짐승을 전혀 실행시키기 위해 한 일과 코드를 "최적화"하는 일과 더 읽기 쉽고 유지하기 쉬운 일을 구별해야한다고 덧붙였다. 가상 메모리를 사용하여 IBM에서 DOE 시뮬레이션 코드를 실행하려고 시도 할 때 VAX 오버레이를 처리 한 것을 기억할 수 있습니다 (제거해야하고 전체가 하나의 주소 공간으로 바뀜).

필자는 적절한 들여 쓰기와 주석을 사용하여 FORTRAN IV 제어 구조를 최소한 FORTRAN 77 수준으로 신중하게 재구성하는 것으로 시작합니다. ASSIGN 및 COMPUTED GOTO 및 산술 IF와 같은 기본 제어 구조를 제거하고 물론 가능한 한 많은 GOTO를 제거하십시오 (IF-THEN-ELSE-ENDIF 사용). 모든 루틴에서 IMPLICIT NONE을 사용하여 모든 변수를 올바르게 선언하도록 강요하십시오 (다른 사람의 코드에서 내가 잡은 버그 (변수 이름의 오타)를 믿을 수 없을 것입니다). 컴파일러가 자체적으로 처리하도록하는 것이 더 낫다는 "미숙 한 최적화"에주의하십시오.

이 코드가 계속 유지되고 유지 관리가 가능하도록하려면 코드를 읽고 이해할 수 있도록 자신과 후임자에게 빚지고 있습니다. 코드를 변경할 때 무엇을하고 있는지 확인하십시오! FORTRAN은 프로그래밍 세계의 C 쪽에서 오는 누군가를 쉽게 넘어 뜨릴 수있는 많은 독특한 구조를 가지고 있습니다. FORTRAN은 50 년대 중반으로 거슬러 올라갑니다. 언어와 컴파일러 디자인에 대한 과학 같은 것이 없었고, 무언가를 함께 임시 해킹하는 것 뿐입니다 (미안합니다, B 박사!).


1

가끔 저를 물어 뜯는 또 다른 것이 있습니다. FORTRAN 코드에서 작업 할 때 6 개의 초기 열을 모두 건너 뛰십시오. 가끔씩 5 개의 공백 만 들여 쓰기 된 코드를 가져 오지만 아무 것도 작동하지 않습니다. 언뜻보기에 모든 것이 괜찮아 보였고 마침내 모든 행이 7 열 대신 6 열에서 시작한다는 것을 알게되었습니다.

FORTRAN에 익숙하지 않은 사람을 위해 처음 5 개 열은 줄 번호 (= 레이블) 용이고, 6 번째 열은 80 자보다 긴 줄이있는 경우 연속 문자 용입니다 (여기에 무언가를 입력하면 컴파일러가이 줄을 알고 있음). 실제로 이전의 일부) 코드는 항상 7 열에서 시작합니다.


6
이 설명은 FORTRAN 77 및 이전 버전에 해당되지만 자유 형식 소스 레이아웃을 사용하는 Fortran 90 이상에는 해당되지 않습니다.
MSB

3
또한 라인은 80 번째가 아닌 72 번째 열에서 끝나야합니다.
Rook
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.