CFDソルバーがあり、シミュレーションの実行中に、一部のマシンでは非常に低速で実行されることがわかりましたが、他のマシンでは実行されませんでした。Intel VTuneを使用すると、次の行が問題であることがわかりました(Fortranの場合)。
RHOV= RHO_INF*((1.0_wp - COEFF*EXP(F0)))**(1.0_wp/(GAMM - 1.0_wp))
VTuneでドリルインすると、問題はcall pow
組立ラインにトレースされ、スタックをトレースすると、を使用していることがわかりました__slowpow()
。いくつか検索した後、このページは同じことについて不平を言っているように見えました。
libcバージョン2.12のマシンでは、シミュレーションに18秒かかりました。libcバージョン2.14のマシンでは、シミュレーションに0秒かかりました。
上記のページの情報に基づくと、ベースがpow()
1.0に近い場合に問題が発生します。そこで、別の簡単なテストを実行しました。このテストでは、ベースの前に任意の数値をスケーリングし、呼び出しpow()
後に指数に累乗した数値で除算しました。pow()
これにより、libc2.12でもランタイムが18秒から0秒に短縮されました。
ただし、これをコード全体に配置することは実用的ではありませんa**b
。pow()
libcの関数をどのように置き換えますか?たとえばcall pow
、Fortranコンパイラーによって生成された組立ラインpow()
で、スケーリングを実行し、libcpow()
を呼び出してから、スケーリングで除算するカスタム関数を呼び出すようにします。コンパイラに対して透過的な中間層をどのように作成しますか?
編集
明確にするために、(擬似コード)のようなものを探しています:
double pow(a,b) {
a *= 5.0
tmp = pow_from_libc(a,b)
return tmp/pow_from_libc(5.0, b)
}
pow
名前の競合を回避するために、from libcをロードし、カスタム関数で名前を変更することは可能ですか?customPow.o
ファイルの名前をlibcから変更できる場合、pow
他の目的でlibcがまだ必要な場合はどうなりますか?pow
それはincustomPow.o
とinlibcの間で名前の競合を引き起こしpow
ますか?