1

ループ内のメモリ呼び出しの数を減らすことについて質問があります。次のコードを検討してください(長すぎるため、ここでは表現できないため、これは私のコードではありません)。

for(k=0;k<n;k++)
{
    y[k] = x[0]*2 + z[1];
}

ご覧のとおり、各反復で、メモリ内の同じブロック(x [0]、z [1])が呼び出されています。同じメモリブロックが複数回呼び出されたときに、メモリアクセスを減らす方法があるかどうか疑問に思いました。前もって感謝します。

4

5 に答える 5

6

単純に、ループの前に値を取得します。

i = x[0];
j = z[1];
for(k=0;k<n;k++)
{
    y[k] = i*2 + j;
}

もちろん、何も変更しなくても、コンパイラはこれを最適化しますが (可能であれば)、より読みやすく直感的なコードを作成するのに役立ちます。すべての反復で値を取得する必要はなく、記述するコードはそれを示している必要があります。
マイクロ最適化を忘れて、より直感的で読みやすいコードを書きましょう!

コメントで正しく指摘されているように、右側の式はループから完全に独立しているため、次のようになります。

i = x[0]*2 + z[1];
for(k=0;k<n;k++)
{
    y[k] = i;
}
于 2013-01-28T05:52:13.067 に答える
2

これがあなたにできることです。

float value =  x[0]*2 + z[1];

for(k=0;k<n;k++)
{
  y[k] = value;
}

お役に立てれば。

于 2013-01-28T05:58:39.770 に答える
1
v = x[0]*2 + z[1];
for(k=0;k<n;++k) y[k] = v

x[0]とz[1]がy[0..n-1]にマップされていないと仮定します。

于 2013-01-28T05:59:14.670 に答える
1

zより短い型int(例) がある場合charは、次のトリックを試すことができます。

char value = x[0]*2 + z[1];
unsigned int value32 = value | (value << 8) | (value << 16) | (value << 24);

unsigned int k;

// Going by blocks of 4
for(k = 0; k < n - n%4; k+=4) {
    (unsigned int)z[k] = value32;
}

// Finishing loop
for(; k < n; k++) {
    z[k] = value;
}
于 2013-01-28T06:53:55.983 に答える
0

コンパイラはこれを最適化し、

ただし、最適化を行わずに壊れたコンパイラを使用する場合は、両方をregister整数に入れて操作することができます。このような:

x0 = x[0]*2;
z1 = z[1];
y0 = x0 + z1;
register int k;
for(k=0;k<n;k++)
{
   y[k] = y0;
}

これは、x[0] と z[1] がレジスターにあることを保証するものではありませんが、少なくともレジスターにある必要があることをコンパイラーに示唆します。

于 2013-01-28T05:55:28.483 に答える