4

現在、コードの一部を最適化しているため、ベンチマークを実行しています。

私はNxN行列Aを持っていTて、それらを要素ごとに乗算し、結果をA再度保存したいと考えていますA = A*T。このコードは並列化できないため、割り当てを次のように拡張しました

!$OMP PARALLEL DO
do j = 1, N
    do i = 1, N
        A(i,j) = T(i,j) * A(i,j)
    end do
end do
!$OMP END PARALLEL DO

( http://pastebin.com/RGpwp2KZにある完全な最小限の作業例。)

現在起こっている奇妙なことは、スレッドの数 (1 から 4 の間) に関係なく、実行時間はほぼ同じ (+-10%) のままですが、スレッドの数が増えると CPU 時間は増加するということです。そのため、すべてのスレッドが同じ作業を行うため (OpenMP に関して間違いを犯したため)、同じ時間が必要であると考えました。

しかし、別のコンピューター (96 個の CPU コアが利用可能) では、プログラムは期待どおりに動作します。スレッド数が増えると、実行時間が減少します。驚くべきことに、CPU 時間も減少します (最大 10 スレッドまで、その後再び増加します)。

OpenMPの異なるバージョンまたはgfortranインストールされている可能性があります。これが原因である場合、それを見つける方法を教えていただければ幸いです。

4

1 に答える 1

9

理論的には、Fortran 固有の OpenMPWORKSHAREディレクティブを使用して、Fortran 配列操作を並列化できます。

!$OMP PARALLEL WORKSHARE
A(:,:) = T(:,:) * A(:,:)
!$OMP END PARALLEL WORKSHARE

これは非常に標準的な OpenMP コードですが、一部のコンパイラー、特にインテル Fortran コンパイラー ( ) は、単に構造体を使用して構造体ifortを実装するため、並列速度がまったく向上しないことに注意してください。一方、このコード フラグメントを暗黙的なループに変換します。として明示的に記述されていない限り、ワークシェアリング コンストラクト内の標準配列表記は並列化されないことに注意してください。WORKSHARESINGLEgfortranPARALLEL DOgfortranA = T * AA(:,:) = T(:,:) * A(:,:)

次に、パフォーマンスとスピードアップの欠如について。Aあなたの行列の各列はバイトTを占有します。(2 * 8) * 729 = 116641 つのマトリックスが 8.1 MiB を占有し、2 つのマトリックスを合わせると 16.2 MiB を占有します。これはおそらく、CPU の最終レベルのキャッシュ サイズを超えています。また、乗算コードの計算強度は非常に低く、反復ごとに 32 バイトのメモリ データをフェッチし、6 つの FLOP で 1 つの複雑な乗算 (4 つの実数乗算、1 つの加算と 1 つの減算) を実行してから、16 バイトをメモリに格納します。(6 FLOP)/(48 bytes) = 1/8 FLOP/byte. メモリが全二重であると見なされる場合、つまり、読み取り中の書き込みをサポートする場合、強度は次のようになります。(6 FLOP)/(32 bytes) = 3/16 FLOP/byte. つまり、問題はメモリ バウンドであり、単一の CPU コアでさえ、使用可能なすべてのメモリ帯域幅を飽和させる可能性があります。たとえば、典型的な x86 コアは、1 サイクルあたり 2 つの浮動小数点演算をリタイアでき、2 GHz で実行すると、4 GFLOP/秒のスカラー演算を実行できます。このようなコアを乗算ループの実行にビジー状態に保つには、メイン メモリが提供する必要があります。(4 GFLOP/s) * (16/3 byte/FLOP) = 21.3 GiB/s. この量は、現世代の x86 CPU の実メモリ帯域幅を多かれ少なかれ超えています。これは、ベクトル化されていないコードを含む単一コアのみです。コアとスレッドを追加してもパフォーマンスは向上しません。これは、メモリがコアをビジー状態に保つのに十分な速度でデータを配信できないためです。むしろ、スレッドが増えるとオーバーヘッドが増えるため、パフォーマンスが低下します。96 コアのようなマルチソケット システムで実行すると、プログラムはより多くの最終レベル キャッシュとより高いメイン メモリ帯域幅 (各 CPU ソケットに個別のメモリ コントローラを備えた NUMA システムを想定) にアクセスできるため、パフォーマンスが向上します。ただし、ソケットの数が多いからであり、コアの数が多いからではありません。

于 2013-07-24T11:28:32.847 に答える