CPU 時間のほとんどを占める私のプログラムの部分は、それに続く 2D ループです。それが行うことはoutput
、512x512 テーブルを使用して512x512 RGB イメージを塗りつぶすことですlut
。各エントリは、1 次元の ~4000 エントリ RGBinput
バッファ内の 4 つのエントリを指し、それらの各入力ピクセルのそれぞれの固定小数点の重みを示します。これの目的は、視覚化のために 1D バッファーを 2D スパイラルにラップすることです。これが、これらのインデックスと重みを計算するのが簡単ではないため、LUT を使用する理由です。
kV
は 512 (出力画像と LUT の次元) であり、すべての構造体のすべてのメンバーはuint16_t
(.r
.g
および.b
含まれており、lut
構造体にも 2 つdouble
の値が含まれています)、その他の値はさまざまな整数オフセットであり、そうでないものもあります。
for (iy=0; iy<kV; iy++)
{
for (ix=0; ix<kV; ix++)
{
output[(iy+ci->vy) * ci->kW + ix+ci->vx].r = (
input[lut[iy*kV+ix].spos0].r * lut[iy*kV+ix].w0 +
input[lut[iy*kV+ix].spos1].r * lut[iy*kV+ix].w1 +
input[lut[iy*kV+ix].spos2].r * lut[iy*kV+ix].w2 +
input[lut[iy*kV+ix].spos3].r * lut[iy*kV+ix].w3) >> 15;
output[(iy+ci->vy) * ci->kW + ix+ci->vx].g = (
input[lut[iy*kV+ix].spos0].g * lut[iy*kV+ix].w0 +
input[lut[iy*kV+ix].spos1].g * lut[iy*kV+ix].w1 +
input[lut[iy*kV+ix].spos2].g * lut[iy*kV+ix].w2 +
input[lut[iy*kV+ix].spos3].g * lut[iy*kV+ix].w3) >> 15;
output[(iy+ci->vy) * ci->kW + ix+ci->vx].b = (
input[lut[iy*kV+ix].spos0].b * lut[iy*kV+ix].w0 +
input[lut[iy*kV+ix].spos1].b * lut[iy*kV+ix].w1 +
input[lut[iy*kV+ix].spos2].b * lut[iy*kV+ix].w2 +
input[lut[iy*kV+ix].spos3].b * lut[iy*kV+ix].w3) >> 15;
}
}
非常に単純ですが、何かが間違っているか、より効率的に実行できると確信しています。各ピクセルで平均約 66 サイクルが得られます (VS2010 と完全な最適化を使用)。か否か?
編集:これは、提案された編集で得られるもので、66 サイクルではなく 36 サイクルです。もっとうまくやれるでしょうか?
for (iy=0; iy<kV; iy++)
{
iykv = iy*kV;
col = (iy+ci->vy) * ci->kW;
for (ix=0; ix<kV; ix++)
{
lutv = lut[iykv+ix];
outptr = &output[col + ix+ci->vx]
outptr->r = (
input[lutv.spos0].r * lutv.w0 +
input[lutv.spos1].r * lutv.w1 +
input[lutv.spos2].r * lutv.w2 +
input[lutv.spos3].r * lutv.w3) >> 15;
outptr->g = (
input[lutv.spos0].g * lutv.w0 +
input[lutv.spos1].g * lutv.w1 +
input[lutv.spos2].g * lutv.w2 +
input[lutv.spos3].g * lutv.w3) >> 15;
outptr->b = (
input[lutv.spos0].b * lutv.w0 +
input[lutv.spos1].b * lutv.w1 +
input[lutv.spos2].b * lutv.w2 +
input[lutv.spos3].b * lutv.w3) >> 15;
}
}