문제

나는 멀티 CPU 시스템에서 미분 방정식을 해결하는 Fortran 프로그램의 성능을 측정하라는 요청을 받았습니다. 고용주는 플롭/S (초당 플로팅 운영)를 측정하고 결과를 벤치 마크와 비교한다고 주장합니다.Linpack) 그러나 나는 그것이 플롭이 무엇인지 아무도 나에게 설명 할 수 없기 때문에 그것이 갈 길이라고 확신하지 않습니다.

나는 플롭이 정확히 무엇인지에 대한 연구를했고 꽤 모순되는 대답을 얻었습니다. 내가 얻은 가장 인기있는 답변 중 하나는 '1 flop = 추가 및 곱셈 작업'이었습니다. 그게 사실인가요? 그렇다면 다시, 물리적으로, 그것은 정확히 무엇을 의미합니까?

내가 사용하는 방법은 확장 가능해야합니다. 코드의 일부 버전은 수백만 미지의 알려지지 않은 시스템을 해결하고 실행하는 데 며칠이 걸립니다.

내 경우에는 성능을 측정하는 다른 효과적인 방법은 무엇입니까 (내 사례 요약 ''수백 CPU에서 며칠 동안 많은 산술 계산을 반복하는 Fortran 코드)?

도움이 되었습니까?

해결책

그것이 측정하는 것을 정확하게 이해하는 한 그것은 꽤 괜찮은 성능 측정입니다.

Flops는 이름이 초당 플로팅 포인트 작업을 의미하므로 플롭을 구성하는 것은 CPU에 따라 달라질 수 있습니다. (일부 CPU는 한 번의 작업으로 추가 및 곱셈을 수행 할 수 있으며, 예를 들어 다른 작업은 할 수 없습니다). 즉, 성능 측정으로 하드웨어에 상당히 가깝기 때문에 1) 주어진 아키텍처에서 이상적인 플롭을 계산하려면 하드웨어를 알아야하며 알고리즘과 구현을 알아야합니다. 많은 부동 소수점 작전이 실제로 구성됩니다.

어쨌든 CPU를 얼마나 잘 활용하는지 검사하는 데 유용한 도구입니다. Flops에서 CPU의 이론적 피크 성능을 알고 있다면 CPU의 부동 소수점 단위를 얼마나 효율적으로 사용하는지 알 수 있습니다. 이는 종종 효율적으로 활용하기가 어렵습니다. CPU가 할 수있는 플롭의 30%를 실행하는 프로그램은 최적화의 여지가 있습니다. 기본 알고리즘을 변경하지 않으면 70%로 실행되는 것은 아마도 훨씬 더 효율적이지 않을 것입니다. 귀하와 같은 수학이 많은 알고리즘의 경우 성능을 측정하는 표준 방법입니다. 프로그램이 실행하는 데 걸리는 시간을 단순히 측정 할 수 있지만 CPU에 따라 크게 다릅니다. 그러나 프로그램에 50% CPU 활용률이있는 경우 (피크 플롭 수와 관련하여), 이는 다소 일정한 값입니다 (여전히 근본적으로 다른 CPU 아키텍처마다 다르지만 실행 시간보다 훨씬 일관성이 있습니다).

그러나 "내 CPU는 X GFLOPS가 가능하며 실제로는 20%의 처리량 만 달성하고 있습니다." 매우 고성능 소프트웨어의 귀중한 정보. 그것은 무언가를 의미합니다 다른 플로팅 포인트 OPS가 당신을 막고 FP 장치가 효율적으로 작동하는 것을 방지합니다. FP 장치가 대부분의 작업을 구성하므로 소프트웨어에 문제가 있음을 의미합니다.

"내 프로그램이 x 분 안에 실행되었다"는 것은 쉽고, 허용 할 수 없다고 생각한다면, 당신은 "내가 그것을 30% 할인 할 수 있는지 궁금해 할 수는 있지만" 알다 정확히 얼마나 많은 작업을 수행하고 있는지, 그리고 CPU가 절정에 달하는 것과 정확히 일치하지 않는 한 가능하다면 가능하다면. CPU가 기본적으로 초당 더 이상 지침을 실행할 수 있는지 여부를 모르는 경우 이것을 최적화하는 데 얼마나 많은 시간을 소비하고 싶습니까?

CPU의 FP 장치가 FP OPS간에 너무 많은 종속성을 갖거나 너무 많은 지점을 갖거나 유사한 효율적인 스케줄링을 사용하여 CPU의 FP 장치가 효율적으로 활용되는 것을 방지하는 것은 매우 쉽습니다. 그리고 그것이 당신의 구현을 다시 유지하고 있다면, 당신은 필요 그것을 아는 것. "나는 가능한 FP 처리량을 얻지 못하므로 CPU가 발행 할 준비가되었을 때 내 코드의 다른 부분이 FP 지침을 사용할 수 없도록하는 것을 알아야한다"고 알아야한다.

성능을 측정하는 다른 방법이 필요한 이유는 무엇입니까? 상사가 당신에게 물었을 때 플롭 계산만으로 운동하는 데 무슨 문제가 있습니까? ;)

다른 팁

몇 가지 더 좋은 점을 추가하고 싶습니다.

  • 분할 특별합니다. 대부분의 프로세서는 단일 주기로 추가, 비교 또는 곱셈을 수행 할 수 있으므로 이들은 모두 하나의 플롭으로 간주됩니다. 그러나 부서는 항상 더 오래 걸립니다. 프로세서에 얼마나 더 길어 지지만, HPC 커뮤니티에는 4 개의 플롭으로 하나의 디비전을 계산하는 일종의 Defacto 표준이 있습니다.

  • 프로세서가있는 경우 융합 곱하기 단일 명령어 (일반적으로 A += B * C)의 곱셈 및 추가를 수행하는 지침은 2 개의 작업으로 간주됩니다.

  • 항상 구별하는 데주의하십시오 단일-----------------------------------------------그는 단일---------------프비는 단일----------------그는 단일----------퍼지 플롭과 이중 프레임 플롭. 너무 많은 단일 정밀 기가 플롭을 가능하게하는 프로세서는 많은 이중 정제 기가 플롭의 작은 부분 만 가능할 수 있습니다. AMD Athlon 및 Phenom 프로세서는 일반적으로 단일 정밀도보다 많은 이중 정제 플롭의 절반을 수행 할 수 있습니다. ATI Firestream 프로세서는 일반적으로 단일 정밀도로 많은 이중 정제 플롭만큼 1/5를 수행 할 수 있습니다. 누군가가 당신에게 프로세서 나 소프트웨어 패키지를 판매하려고한다면, 그들은 말하지 않고 Flops를 인용하는 경우, 당신은 그것들을 호출해야합니다.

  • Megaflop, Gigaflop, Teraflop 등이라는 용어는 일반적으로 사용됩니다. 이것들은 요인을 나타냅니다 1000, 1024가 아닙니다. 예를 들어, 1 메가 플롭 = 1,000,000 플롭/초 1,048,576이 아닙니다. 디스크 드라이브 크기와 마찬가지로 이것에 대해 약간의 혼란이 있습니다.

"결과를 벤치 마크와 비교하고"무엇을합니까?

플롭은 당신이 필요하다는 것을 의미합니다

1) 일부 작업 단위 당 플롭.

2) 해당 작업 단위의 시간.

일부 루프를 통해 1,000 개의 반복을 수행하는 입력 파일이 있다고 가정 해 봅시다. 루프는 편리한 작업 단위입니다. 1,000 번 실행됩니다. 1 시간이 걸립니다.

루프에는 약간의 추가 및 곱하기가 있으며 몇 가지 분할 및 제곱근이 있습니다. 추가, 곱하기 및 분열을 계산할 수 있습니다. +, * 및 /를 찾는 소스에서 이것을 계산할 수 있습니다. 컴파일러에서 어셈블러 출력을 찾아서 계산할 수 있습니다. 다른 숫자를 얻을 수 있습니다. 어느 것이 맞습니까? 상사에게 물어보세요.

당신은 정사각형 뿌리를 계산할 수 있지만, 곱셈과 추가 측면에서 그것이 실제로 무엇을하는지 모릅니다. 따라서 벤치 마크 Multiply vs. Square Root와 같은 작업을 수행하여 제곱근이 얼마나 오래 걸리는지 알 수 있습니다.

이제 당신은 당신의 루프의 플롭을 알고 있습니다. 그리고 당신은 그것을 1,000 번 실행할 시간을 알고 있습니다. 당신은 초당 플롭을 알고 있습니다.

그런 다음 Linpack을보고 느리게 느낍니다. 이제 뭐? 귀하의 프로그램은 Linpack이 아니며 Linpack보다 느립니다. 코드가 느려질 확률은 정말 좋습니다. 코드가 같은 수년에 걸쳐 Linpack에 걸쳐 작성되고 최적화되지 않으면 느리게됩니다.

다른 부분이 있습니다. 프로세서에는 다양한 벤치 마크에 대해 정의 된 FLOPS 등급이 있습니다. 알고리즘은 이러한 벤치 마크 중 하나가 아니므로 벤치 마크에 미치지 못합니다. 이게 나쁘니? 아니면 이것이 벤치 마크가 아닌 명백한 결과입니까?

실행 가능한 결과는 얼마입니까?

일부 벤치 마크 코드베이스에 대한 측정은 알고리즘이 벤치 마크 알고리즘이 아니라는 것을 알려줍니다. 당신이 다르다는 것은 확실한 결론입니다. 일반적으로 느리게.

분명히 Linpack에 대한 측정 결과는 (a) 당신이 다르기 때문에 (b) 최적화해야합니다.

측정은 반대 할 때만 실제로 가치가 있습니다 당신 자신. 가상의 지시 믹스가 아니라 자신의 지시 믹스. 자신의 성능을 측정하십시오. 변경하십시오. 자신과 비교할 때 자신의 성과가 더 나아지거나 악화되는지 확인하십시오.

플롭은 중요하지 않습니다. 중요한 것은 작업 단위당 시간입니다. 하드웨어 설계자가 기대하는 벤치 마크를 실행하지 않기 때문에 하드웨어의 설계 매개 변수와 일치하지 않습니다.

Linpack은 중요하지 않습니다. 중요한 것은 코드 기반과 성능을 변경하려는 변경 사항입니다.

오래된 질문은 인기가 있다면 정확히 크지 않은 대답, IMO.

"플롭"은 부동 소수점 수학 작업입니다. "플롭"은 두 가지를 의미 할 수 있습니다.

  • "플롭"의 간단한 복수 엑스 50 개의 플롭을 가져갑니다”)
  • 그만큼 비율 첫 번째 의미에서 플롭의 (예 : 초당 부동 소수점 수학 작업)

상황에서 명확하지 않은 경우, 이들 중 의미는 종종 전자를“플롭”으로, 후자는“플롭/S”로 글을 쓰면서 명확하게 표현됩니다.

플롭은 소위 다른 종류의 CPU 작업과 구별하기 위해 소위입니다., 정수 수학 운영, 논리적 운영, 비트 운영, 메모리 작업 및 분기 작업과 같은 비용 ( ""시간이 다르기 "읽기)과 관련하여 이들과 관련하여.

"플롭 카운팅"의 관행은 과학 컴퓨팅의 초기 시절로 거슬러 올라갑니다. 플롭은 비교적 말하면 매우 비싸고 각각 많은 CPU 사이클을 복용했습니다. 예를 들어, 80387 수학 공동 프로세서는 단일 곱셈을 위해 300 사이클과 같은 시간을 보냈습니다. 이것은 파이프 라인 전과 CPU 클럭 속도와 메모리 속도 사이의 걸프가 실제로 열리기 전에 한 번에있었습니다. 메모리 작업은 한두주기에 불과했고 분기 (“의사 결정”)는 비슷하게 저렴했습니다. 당시에는 12 개의 메모리 액세스에 찬성하여 단일 플롭을 제거 할 수 있다면 이득을 얻었습니다. 12 개의 가지를 위해 단일 플롭을 제거 할 수 있다면, 당신은 얻었습니다. 그래서, 과거에는 플롭을 세고 메모리 참조와 가지에 대해 크게 걱정하지 않는 것이 합리적이었고, 플롭은 실행 시간을 강력하게 지배했기 때문입니다. 그들은 다른 종류의 수술에 비해 개별적으로 매우 비싸기 때문입니다.

최근에는 상황이 반전되었습니다. 플롭은 매우 저렴 해졌습니다 핵심 주기당 약 2 개의 플롭을 수행 할 수 있습니다 (부문은 비교적 비싸지 만) - 메모리 액세스와 가지가 비교적 훨씬 비싸다 : L1 캐시 적중 비용은 3 또는 4 사이클, 메인 메모리의 메인 메모리 비용은 150-200입니다. 이 반전을 감안할 때 메모리 액세스에 찬성하여 플롭을 제거하는 것은 더 이상 그렇지 않습니다.; 사실, 그것은 거의 가능하지 않습니다. 마찬가지로, 플롭이 중복 되어도할지 여부를 결정하기보다는 플롭을“그냥”하는 것이 더 저렴합니다. 이것은 25 년 전 상황과 거의 반대입니다.

불행히도, 알고리즘 장점의 절대적인 지표로서 블라인드 플롭 카운팅의 관행은 판매 날짜를 지나서 잘 지속되었습니다. 현대 과학 컴퓨팅은 메모리 대역폭 관리에 관한 것입니다. - 실행 장치를 유지하려고합니다 하다 플롭은 플롭의 수를 줄이는 것보다 끊임없이 데이터를 공급합니다. 에 대한 참조 Linpack (본질적으로 쓸모없는 라크 20 년 전)는 당신의 고용주가 아마도 성과 기대치를 설정하는 것이 플롭을 더 이상 세는 것의 문제가 아니라는 사실을 내면화하지 않은 매우 오래된 학교라고 의심하게 만듭니다. 훨씬 더 많은 플롭을 수행하는 솔버는 훨씬 더 유리한 메모리 액세스 패턴 및 데이터 레이아웃을 가지고 있다면 여전히 다른 것보다 20 배 빠를 수 있습니다.

이 모든 것의 상승은 그 것입니다 계산 집약적 인 소프트웨어의 성능 평가는 예전보다 훨씬 더 복잡해졌습니다.. 플롭이 저렴 해졌다는 사실은 거대한 사람들에 의해 매우 복잡합니다. 변동성 메모리 작업 및 분기 비용. 평가에 관해서 알고리즘, 간단한 플롭 계산은 더 이상 전반적인 성능 기대치를 알려주지 않습니다.

아마도 성과 기대와 평가에 대한 더 나은 사고 방법은 소위에 의해 제공됩니다. 지붕 라인 모델, 완벽하지는 않지만 당신을 만드는 이점이 있습니다. 부동 소수점과 메모리 대역폭 문제 사이의 상충 관계에 대해 동시에 생각하십시오., 성능 측정 및 성능 기대치를 비교할 수있는보다 유익하고 통찰력있는 "2D 사진"을 제공합니다.

볼만한 가치가 있습니다.

당신이 말했듯이, 플롭은 초당 부동 소수점 작동입니다. 예를 들어, 작업에 정확히 1 초가 걸리면 (예 : 추가, 빼기, 곱하거나, 결과를 반환하고) 성능은 단순히 1 개의 플롭입니다. 최근의 CPU는 여러 기가 플롭, 즉 초당 수십억 개의 부동 소수점 작업을 쉽게 달성 할 수 있습니다.

나는 단지 가능한 빨리 가려고 노력할 것이며, 특히 피할 수있는 기능 호출이있는 경우 시간을 보내는 위치를 찾아야합니다.

나는 그것이 달리는 동안 몇 번 방해하고 그것이 무엇을하고 있는지 보는 간단한 방법으로 이것을한다. 다음은 내가 찾은 것들입니다.

  • 대부분의 시간은 미분 및/또는 야곱을 계산하는 과정에 있습니다. 이 시간의 대부분은 수학 기능 호출에 들어갈 수 있습니다. exp(), log(), 그리고 sqrt(). 종종 이것들은 동일한 논증으로 반복되며 메모질을 할 수 있습니다. (대규모 속도.)

  • 통합 공차가 필요한 것보다 더 단단하기 때문에 대부분의 시간은 파생 상품을 너무 많이 계산하는 데 소비됩니다. (더 빠르게)

  • 방정식이 뻣뻣하다고 생각되기 때문에 암시 적 통합 알고리즘 (예 : DLSODE 기어)을 사용하는 경우, 가능성이 없으며 Runge-Kutta와 같은 것이 사용될 수 있습니다. (dverk). (더 빨리)

  • 모델이 선형 (DGPADM) 인 경우 매트릭스-단기 알고리즘을 사용할 수 있습니다. 이것은 성능과 정밀도 모두에서 큰 승리이며 강성에 면역이됩니다. (더 빠른 길)

  • 콜 스택이 높을수록, 해당 매개 변수에 대한 솔루션의 전방 또는 중앙 차이 구배를 결정하기 위해 약간 다른 매개 변수로 동일한 통합이 반복적으로 수행 될 수 있습니다. 미분 방정식 자체가 차별화되면, 이러한 그라디언트를 분석적으로 가져 오거나 감도 방정식으로 방정식을 증강시킴으로써 가능할 수 있습니다. 이것은 훨씬 빠르고 훨씬 더 정확하며, 스택 위로 더 높이 올라갈 수 있습니다.

각 수준의 스택을 최적화 할 물건을 찾을 수있는 기회로 볼 수 있으며 속도가 복잡해질 수 있습니다. 그런 다음 Multi-CPU로 이동하면 병렬화 가능하다고 가정하면 자체 곱셈 요소를 제공해야합니다.

플롭으로 돌아갑니다. 당신은 시도 할 수 있습니다 최대화 FLOPs / second, 그러나 그것은 또한 훨씬 더 유용 할 수 있습니다. 최소화 FLOPs / run, 스택의 모든 레벨에서 최적화함으로써. 어쨌든, 그냥 자질 그들은 거의 아무것도 말하지 않습니다.

고용주가 옳습니다.
Fortran 프로그램 (또는 다른 프로그램, BTW)의 효과를 측정하는 유일한 방법은 존재하는 경우 표준 벤치 마크에서이를 테스트하는 것입니다.

그리고 플롭에 대해 "초당 부동 소수점 작업"을 나타냅니다. 정의 Wikipedia에서.

나는 플롭을 측정하는 것이 매우 유용하다고 생각하지 않습니다.

달성 된 플롭의 수는 알고리즘이 CPU를 얼마나 바쁘게 유지하고 있는지 알려주지 만 알고리즘 자체가 얼마나 잘 수행되는지는 알려주지 않습니다.

프로세서가 동일한 수의 플롭을 수행하게하는 두 가지 알고리즘을 찾을 수 있지만 하나는 반 시간에 원하는 결과를 제공합니다.

시간당 단위당 해결 된 미분 방정식의 수와 같은 '높은 수준'통계를 보는 것이 더 나을 것이라고 생각합니다 (즉, 알고리즘의 목적).

반면에, 플롭의 수를 측정하면 CPU를 얼마나 바쁘게 지낼 수 있는지 알 수 있으므로 알고리즘을 개선하는 데 도움이 될 수 있습니다.

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