浮動小数点は決定論的です。同じハードウェアで実行される同じ浮動小数点演算は、常に同じ結果を生成します。黒い魔法、ノイズ、ランダム性、ファジング、または人々が一般的に浮動小数点に帰する他のことはありません。歯の妖精は現れず、結果の低い部分を取り、枕の下に4分の1を残します。
とはいえ、大規模な並列計算に一般的に使用される特定のブロックされたアルゴリズムは、浮動小数点計算が実行される順序に関して非決定的であり、実行全体でビットが正確でない結果になる可能性があります。
あなたはそれについて何ができますか?
まず、あなたが実際にその状況に耐えられないことを確認してください。並列計算で順序付けを強制しようとする可能性のある多くのことは、パフォーマンスを低下させます。それがまさにその通りです。
また、ブロックされたアルゴリズムはある程度の非決定性をもたらす可能性がありますが、単純なブロックされていないシリアルアルゴリズムよりも丸め誤差が小さい結果をもたらすことがよくあります(驚くべきことですが本当です!)。ナイーブなシリアルアルゴリズムによって生成されたエラーを処理できる場合は、並列ブロックアルゴリズムのエラーを処理できる可能性があります。
さて、本当に、本当に、実行全体で正確な再現性が必要な場合は、パフォーマンスにあまり悪影響を与えない傾向があるいくつかの提案があります。
浮動小数点計算を並べ替えることができるマルチスレッドアルゴリズムを使用しないでください。問題が解決しました。これは、マルチスレッドアルゴリズムをまったく使用できないことを意味するのではなく、個々の結果が同期ポイント間の単一のスレッドによってのみアクセスされるようにする必要があるだけです。これを適切に実行すると、コア間のD $競合を減らすことで、一部のアーキテクチャのパフォーマンスを実際に向上させることができることに注意してください。
リダクション操作では、各スレッドに結果を配列内のインデックス付きの場所に格納させ、すべてのスレッドが終了するのを待って、配列の要素を順番に蓄積することができます。これにより、少量のメモリオーバーヘッドが追加されますが、特にスレッドの数が「少ない」場合は、一般的にかなり許容できます。
並列処理を引き上げる方法を見つけます。それぞれが並列アルゴリズムを使用する24個の行列乗算を計算する代わりに、それぞれが直列アルゴリズムを使用する24個の行列積を並列に計算します。これもパフォーマンスに有益です(時には非常にそうです)。
これを処理する方法は他にもたくさんあります。それらはすべて思考とケアを必要とします。並列プログラミングは通常そうします。