-1

私は 3D シミュレーション用のコードを書いているので、コードは次のような内容でいっぱいです。

関数を使用するとオーバーヘッドが発生する可能性がありますか? なぜ?

「a」は 3D ポインターです。

アップデート

関数の定義

double update_a(double a[][JE][KE],...)
{

for(i=1;i<IE;i++){
    for(j=1;j<JE;j++){
        for(k=1;k<KE;k++){
            curl_h=(hz[i][j][k]-hz[i][j-1][k]-hy[i][j][k]+hy[i][j][k-1]);
            idxl[i][j][k]=idxl[i][j][k]+curl_h;
            a[i][j][k]=gj3[j]*gk3[k]*dx[i][j][k]+gj2[j]*gk2[k]*.5*(curl_h+gi1[i]*idxl[i][j][k]);
        }}}

IE=JE=KE=200

どちらの方がよいですか :

 int main()
{
 update_a(...)}

また

int main(){
 for (i=0; i<200; i++) {
    for (j=0; j<200; j++) {
        for (k=0; k<200; k++) {
             curl_h=(hx[i][j][k]-hx[i][j][k-1]-hz[i][j][k]+hz[i-1][j][k]);

                idyl[i][j][k]=idyl[i][j][k]+curl_h;
                a[i][j][k]=gi3[i]*gk3[k]*ey[i][j][k]+gi2[i]*gk2[k]*0.5*(curl_h+gj1[j]*idyl[i][j][k]);
        }
    }
}
 }

更新2:

私の正確なコードは次のようになります。

int main()
    {
for(n=1;n<100000;n++){
     update_a(...);
update_a2(...);
.
.
.
update_a30(...);}}
4

6 に答える 6

3

コードを関数に格納するとオーバーヘッドが発生する可能性があり、何かが 1 秒間に 1000 回呼び出されると蓄積し始めますが、さまざまなコンパイラの最適化に適した場所がたくさんあることに注意してください。ループ (これはフレームごとのデータであるため、3D シミュレーション用の通常の更新ロジック関数が配置される場所です)。テスト中に問題が見つかった場合にのみ、「手動最適化モード」に入る可能性があります。

ただし、実際に「3D」ポインター (T***) を使用している場合は、実際の anon を連続して割り当てるだけなので、ほとんどのオーバーヘッドが発生します。ポインターへのポインターの配列。つまり、特定の要素のアドレスは、メモリ内に線形に配置される T[m][n][q] 配列の場合のように自明に計算できないため、すべての間接化は深刻なコストがかかることを意味します (そして、ポインター、おそらくそれがあなたが言及しているものです)。次に、メモリと CPU のパフォーマンスの不一致によるオーバーヘッドが発生します。

于 2012-05-31T21:03:19.997 に答える
2

関数呼び出しのパフォーマンスの低下は、提供したコードの実行時間と比較して重要ではありません。

于 2012-05-31T20:52:47.063 に答える
2

時期尚早の最適化は良くありません!

関数を使用し、コードがインライン化されていることが判明して発行された場合にのみ、コードをインライン化する必要があります。(プロファイリング ツールとパフォーマンス テストを使用)

関数のオーバーヘッドは、コードを考えると、特に無視できます。

とにかく、多くのコンパイラは必要に応じて関数をインライン化します。つまり、実行するインライン化はパフォーマンスに影響を与えず、メンテナンスとコードの読みやすさの問題につながります。

于 2012-05-31T20:58:07.697 に答える
1

関数呼び出しは、スタックやその他のものを作成するためのパフォーマンスをわずかに低下させます。

しかし、あなたの場合は問題ではありません。なぜなら、コードは数行しかないからです(仮定)。

于 2012-05-31T20:56:28.173 に答える
1

あなたが話している関数がループ内で呼び出されると仮定します:

最新の C++ コンパイラでは、関数はほぼ確実にインライン化されます。たとえば g++ で試してみると、関数呼び出しで生成されたマシン コードが、関数呼び出しなしで生成されたマシン コードと同じであることがわかるはずです。

関数呼び出しがループの外にある場合、コンパイラが関数をインライン化するかどうかは、関数が使用されるコンテキストに依存します。

于 2012-05-31T20:50:45.830 に答える
1

大きな違いはありません。関数は で一度だけ呼び出されmainます。したがって、関数呼び出しのオーバーヘッドがあったとしても、プログラムの実行ごとに 1 回だけ支払われます。プログラムを実行するために必要なすべての作業と比較すると、1 つの余分な関数のエントリとリターンは取るに足らないものです。

自明ではない可能性がある 1 つの方法があります。それは、表示されていない引数の 1 つが...値によって渡され、コピーするのに非常にコストがかかる場合です。ただし、あなたが示したものは単なるポインターであるため、コピーするのに費用はかかりません.

于 2012-05-31T23:56:02.793 に答える