オーバーヘッドとは何ですか?複数の種類のオーバーヘッドがありますか、それとも1つだけですか?いくつかの例は何ですか?
4 に答える
オーバーヘッドとは、特定のリソースの使用であり、実際に達成しようとしていることの副作用です。たとえば、構造体のパディングはメモリオーバーヘッドの一形態です。スタックで引数をプッシュおよびポップすることは、処理オーバーヘッドの一形態です。パケットヘッダーは、帯域幅のオーバーヘッドの一形態です。リソースについて考えると、それに関連するオーバーヘッドが発生する可能性があります。
構造体とクラスのサイズオーバーヘッドの例を次に示します。
struct first {
char letter1;
int number;
char letter2;
};
struct second {
int number;
char letter1;
char letter2;
};
int main ()
{
cout << "Size of first: " << sizeof(first) << endl;
cout << "Size of second: " << sizeof(second) << endl;
return 0;
}
結果は次のとおりです。
Size of first: 12
Size of second: 8
コンパイラーは、単語に合わせて構造体を構築する必要があります。最初の構造体では、周囲の文字(それぞれ1バイト)により、コンパイラーはintを「プッシュ」して、フルワード(4バイト)としてアクセスできるようにします。2番目の構造体は、ほとんどプッシュする必要はありません。
話の教訓:同じサイズのデータメンバーを並べて配置します。
キャッシュを活用するためのローカリティのより良い使用に関連する時間オーバーヘッドの例を次に示します。
#include <stdio.h>
#define SIZE 1024
double A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
int main ()
{
int i, j, k;
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
for (k = 0; k < SIZE; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
return 0;
}
私のマシンでこれを実行するには、これだけの時間がかかります。
real 0m35.137s
user 0m34.996s
sys 0m0.067s
次に、jループとkループの反復を交換します。
#include <stdio.h>
#define SIZE 1024
double A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
int main ()
{
int i, j, k;
for (i = 0; i < SIZE; i++) {
for (k = 0; k < SIZE; k++) { // this is the only change
for (j = 0; j < SIZE; j++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
return 0;
}
このためのランタイムは次のとおりです。
real 0m5.489s
user 0m5.436s
sys 0m0.040s
ループの反復が配列インデックスの順序とより一致するため、はるかに高速です。したがって、データは連続してアクセスされる可能性が高く、したがってキャッシュで利用可能である可能性が高くなります。