定数ポインターとして関数に渡す構造体があります。質問は次のとおりです。関数updatedFieldsの2つの実装には違いがあります。
typedef struct
{
int spec[100];
int spec1[200];
int spec2[200];
int spec3[500];
int spec4[100];
int spec5[700];
float value[100];
char desc[1000]:
}t_product;
void updateFields_1(t_product const* context)
{
int i,buffer[1500];
int * pt_int;
pt_int = (int*)context->spec1;
for(i = 0; i < 200; i++)
{
buffer[i] = pt_int[i];
}
pt_int = (int*)context->spec3;
for(i = 0; i < 500; i++)
{
buffer[i] = pt_int[i];
}
...
}
void updateFields_2(t_product const* context)
{
int i,buffer[1500];
for(i = 0; i < 200; i++)
{
buffer[i] = context->spec1[i];
}
for(i = 0; i < 500; i++)
{
buffer[i] = context->spec3[i];
}
...
}
int main(void)
{
t_product prod;
/* Initialisation of the structure */
...
updateField(&prod);
}
つまり、構造体のメンバーに直接アクセスする代わりに、構造体のメンバーへのポインター(配列へのポインター)を使用する利点があります。
おそらくばかげた質問ですが、構造体メンバーへのアクセスにさらに多くの操作が「かかる」かどうかはわかりません。
あなたの場合、それ以上の費用はかかりません。最適化がなくても。実際、pt_int
最適化を有効にしないと、例が少し悪化する可能性があります。
これは、context->spec3[i]
がより多くのポインタを逆参照していないためですpt_int[i]
。pt_int[i]
は単なるポインタとオフセットであるため、アクセスは@(ptr_int + 4*i)
。として記述できます。ではcontext->spec3[i]
、逆参照されたポインタがもう1つあるように見えるかもしれませんが、そうではありません。spec3
の値ではなく、context
コンテキストからのオフセットにすぎません。したがって、アクセスするアドレスはになります@(context + 2000 + 4*i)
。ポインタアクセスは1つだけです。
今、あなたは@(context + 2000 + 4*i)
より多くの費用がかかるかどうか疑問に思うことができます@(ptr_int + 4*i)
。x86、AMD64、ARM(つまり、100%パーソナルデバイス)を含むほとんどのアーキテクチャには、一定のオフセットでアクセスを行うための命令があるため、そうではありません。また、簡単な最適化を有効にするとすぐに違いがなくなるcontext + 2000
可能性があります。これは、単一に変換できるためですcontext_2000
(ただし、パフォーマンスを悪化させるだけなので、コンパイラーは実際にはそれを行いません)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加