2017-12-26 72 views
-2

CでのARMネオンコンパイラの利点を利用して、画像のフィルタの畳み込みを最適化するガイドがありますか?私はすでにこれを従来のC言語で実装していますが、NEONをサポートしてARM上でより高速な画像処理を行うためにコードを時間最適化する必要があります。インターネットで利用可能なリソースは、CでNEONを使用してARMでアルゴリズムを実装する場合、非常に制限されます。NEONを使用してARMの畳み込み演算を最適化する

3x3フィルタに画像をコンボリューションする必要があります。私が推測する主な問題は、ループ制約が画像の3x3マトリックスにアクセスすることです。 NEON組み込み関数は、8バイトのデータを一度にロードするのに役立ちますが、3x3マトリックスにアクセスするには、これをどのように活用するのですか?上記のコメントでは、今、私はこのような3×3の画像行列にアクセスしてるために Convolution Example

for(i=1;i<width;i++) // i = rows                          
     {                            
       if(i!=1)                              
         fseek(fp, 1078+(width*(i-1)), SEEK_SET);                    
       for(j=1;j<height-1;j++) // j = columns                       
       {                                
         if(j!=1)                            
           fseek(fp, 1077 + (i*width) + j , SEEK_SET);                  
         for(k=0;k<9;k+=3)                          
         {                              
           data[k] = getc(fp);                        
           data[k+1] = getc(fp);                       
           data[k+2] = getc(fp);                       
           //fread(buf, sizeof(char), width - 3, fp);                  
           fseek(fp, width - 3, SEEK_CUR);                     
         }                              
         pixel = vld1_u8(&data);                         
         pixel_last = data[8];                      
         result = vmul_u8(kernel,pixel);                       

         for(k=0;k<8;k++)                          
           sum += result[k];                        

         sum += pixel_last * kernel_last;                      
         sum = sum/9;                           
         sum = sum > 255 ? 255 : sum;                       
         imageData[i*width + j]= sum;                       

       }                                

     }        
+0

、私がやったことです:https://codereview.stackexchange.com – Vagish

+3

まず、あなたのフィルタリングコードからファイルI/Oを分離します。 1つの関数を使用して画像データをメモリ内のソースバッファに読み込み、フィルタリングルーチンを適用してソースバッファから読み込み、その出力を2番目のバッファに書き込むようにします。これにより、フィルタリングを実装するのがはるかに簡単になります。また、(より遅い)ファイルI/Oとは別に、最適化されたフィルタリングコードをベンチマークすることもできます。 –

+1

'intrinsics'で読書を止めました。 –

答えて

1

@PaulRからの答えは、トリックを行いました。画像データを一度にバッファーに読み込んだ後、フィルターアルゴリズムを適用すると、タイミングはほぼ10倍に減少しました。ここで

はあなたがここにあなたの質問をPOSYでき

fread(imageData, sizeof(unsigned char), imgDataSize, fp);          

for(i=0;i<width;i++) // i = rows                  
     {                   
       start_1= clock();          
       for(j=0;j<height;j++) // j = columns          
       {                      
         for(k=0;k<9;k+=3)                  
         {               
           data[k] = imageData[i*width + j]; 
           data[k+1] = imageData[(i+1)*width + (j+1)];    
           data[k+2] = imageData[(i+2)*width + (j+2)];       
         }                      
         pixel = vld1_u8(&data);          
         pixel_last = data[8];          
         result = vmul_u8(kernel,pixel);               

         for(k=0;k<8;k++)       
           sum += result[k];          

         sum += pixel_last * kernel_last;              
         sum = sum/9;             
         sum = sum > 255 ? 255 : sum;    
         newimageData[i*width + j]= sum;         

       }                        
     }                          
+0

上記のフィルタコードをより効率的にするためにはまだまだ多くのことがありますが、十分速い場合はそのままそのまま残すことができます。 –

+0

あなたはもっと何が@PaulRできるのか説明できますか?私は知りたいです。より効率的に、より良い。 –

+1

あまりにも多くの冗長なスカラーコードがあり、ちょうど2つの主要な問題を指摘するために、連続していないメモリを反復処理しています。あなたがhttp://codereview.stackexchange.comに適切にタグ付けされた質問を掲載している場合(これは動作しているコードなので)、現在の機能コードに基づいて[mcve]があることを確認してください。それを改善するための提案。 –

関連する問題