0

496*O(N^3) ループがあります。一度に 1 つではなく 2 つの画像を操作するブロッキング最適化手法を実行しています。生の用語では、外側のループを展開しています。(コードの展開されていないバージョンは以下のとおりです:) ところで、私は 8 コアの Intel Xeon X5365 マシンを使用しており、クロックは 3 GHz、バス周波数は 1333 MHz、共有 8 MB L2 (2 コアごとに 4 MB が共有) です。 、L1-I 32KB、L1-D 32KB。

for(imageNo =0; imageNo<496;imageNo++){
for (unsigned int k=0; k<256; k++)
{
double z = O_L + (double)k * R_L;
for (unsigned int j=0; j<256; j++)
{
    double y = O_L + (double)j * R_L;

    for (unsigned int i=0; i<256; i++)
    {
        double x[1] = {O_L + (double)i * R_L} ;             
        double w_n =  (A_n[2] * x[0] + A_n[5] * y + A_n[8] * z + A_n[11])  ;
        double u_n =  ((A_n[0] * x[0] + A_n[3] * y + A_n[6] * z + A_n[9] ) / w_n);
        double v_n =  ((A_n[1] * x[0] + A_n[4] * y + A_n[7] * z + A_n[10]) / w_n);                      

        for(int loop=0; loop<1;loop++)
        {
            px_x[loop] = (int) floor(u_n);
            px_y[loop] = (int) floor(v_n);
            alpha[loop] = u_n - px_x[loop] ;
            beta[loop]  = v_n - px_y[loop] ;
        }
       if(px_y[0]>=0 && px_y[0]<(int)threadCopy[0].S_y)
            {
                if (px_x[0]>=0 && px_x[0]<(int)threadCopy[0].S_x )
                    ///////////////////(i,j) pixels ///////////////////////////////
                    pixel_1[0] = threadCopy[0].I_n[px_y[0] * threadCopy[0].S_x + px_x[0]];
                else
                    pixel_1[0] =0.0;                                    

                if (px_x[0]+1>=0 && px_x[0]+1<(int)threadCopy[0].S_x)
                    /////////////////// (i+1, j) pixels/////////////////////////
                    pixel_1[2] = threadCopy[0].I_n[px_y[0] * threadCopy[0].S_x + (px_x[0]+1)];
                else
                    pixel_1[2] = 0.0;       
            }
            else{
                pixel_1[0] =0.0;                                    
                pixel_1[2] =0.0;                                    
            }

            if( px_y[0]+1>=0 && px_y[0]+1<(int)threadCopy[0].S_y)
            {

                if (px_x[0]>=0 && px_x[0]<(int)threadCopy[0].S_x)
                    pixel_1[1] = threadCopy[0].I_n[(px_y[0]+1) * threadCopy[0].S_x + px_x[0]];
                else
                    pixel_1[1] = 0.0;


                if (px_x[0]+1>=0 && px_x[0]+1<(int)threadCopy[0].S_x)
                    pixel_1[3] = threadCopy[0].I_n[(px_y[0]+1) * threadCopy[0].S_x + (px_x[0]+1)];
                else 
                    pixel_1[3] = 0.0;
            }
            else{
                pixel_1[1] = 0.0;
                pixel_1[3] = 0.0;
            }

                pix_1 = (1.0 - alpha[0]) * (1.0 - beta[0]) * pixel_1[0] + (1.0 - alpha[0]) * beta[0]  * pixel_1[1]
                +  alpha[0]  * (1.0 - beta[0]) * pixel_1[2]   +  alpha[0]  *  beta[0]  * pixel_1[3];                    

            f_L[k * L * L + j * L + i] += (float)(1.0 / (w_n * w_n) * pix_1);
}

}
}

Intel Vtune-2013 (gcc-4.1 から作成されたバイナリを使用) を使用して結果をプロファイリングしたところ、反復ごとに 2 つの画像が処理されるため、メモリ帯域幅の使用量が 40% 削減されていることがわかります。ボクセルごとに 8 バイトのトラフィック)。これにより、バス サイクルが 11.7% 削減されます。また、内側のループでブロックサイズが大きくなるため、リソースのストールが 25.5% 減少します。これら 2 つは、応答時間が 18% 短縮されたことを示しています。謎の質問は、なぜ引退した指導者が 7.9% 増加したのかということです。(これにより、応答時間が 6.51% 増加しました) - 考えられる理由は次のとおりです。 1. ブロック内で分岐命令の数が増加するため (コア アーキテクチャには 8 ビットのグローバル履歴があるため)、廃止された分岐命令は 2.5% 増加しました。 ( それでも、誤算は相変わらず!私は知っています、魚のにおいがしますよね?!!)。しかし、残りの 5.4% についてはまだ回答がありません。誰か私に光を当ててください。私は完全に選択肢がなく、考える方法がありません。どうもありがとう!!

4

0 に答える 0