簡體   English   中英

使用Intel內部函數進行位反向重新排序優化

[英]Bit reverse reorder optimization using Intel intrinsics

前一陣子,我使用SSE內在函數優化了radix2函數,並且我幾乎接近FFTW性能,因此,下一步,我要優化我在原始代碼中發現的位反向重排序函數,說實話,我想要優化它。 原始代碼如下:

void bit_reverse_reorder(float *x,float *y, int N)
{
   int bits=0;
   int i, j, k;
   float tempr, tempi;
   //MAXPOW = 12

   for (i=0; i<MAXPOW; i++)
      if (pow_2[i]==N) bits=i;

   for (i=0; i<N; i++)
   {
      j=0;
      for (k=0; k<bits; k++)
         if (i&pow_2[k]) j+=pow_2[bits-k-1];
      if (j>i)
      {
        tempr=x[i];
        tempi=y[i];
        x[i]=x[j];
        y[i]=y[j];
        x[j]=tempr;
        y[j]=tempi;
      }
   }
}

int main()
{
   radix2(re,im,N);

   bit_reverse_reorder(re,im,N);
}

PS :pow_2 []是一個預先計算的數組,包含2的冪(1,2,4,8,16,32,...),N是元素數= 4096,* x和* y分別表示,輸入數據每個元素的實部和虛部。

radix2生成未排序的結果,因此指定的函數將結果重新排序。

首先,我不完全了解該位反轉的工作原理! 因此,我認為如果有人給我有關此功能的工作原理的提示會很好。

其次,我打算使用SSE內在函數來增強此功能的性能,因此在交換循環中是否可以使用2條指令的向量?

感謝@nwellnhof評論,我對交換功能做了如下修改:

void bit_reverse_reorder(float *x,float *y, int N)
{
   unsigned i,j;
   for (i = 0, j = 0; i < N; i++) {
      if (i < j) 
      {
         float tmpx = x[i];
         x[i] = x[j];
         x[j] = tmpx;

         float tmpy = y[i];
         y[i] = y[j];
         y[j] = tmpy;
      }
      unsigned bit = ~i & (i + 1);

      unsigned rev = (N / 2) / bit;

      j ^= (N - 1) & ~(rev - 1);
   }
}

現在我在函數內部的for循環中獲得了54 900個循環的性能,這也很好:)

根據您的建議,我進行了一些修改,以增強功能性能。

首先,我通過轉移指令替換了power_2 []調用。

然后,我制作了一個交換函數,該函數使用添加/子操作進行交換,而無需使用第三個變量。

void swap(float* a, float* b)
{
 *a = *a+*b;
 *b = *a-*b;
 *a = *a-*b;
}

void bit_reverse_reorder(float *x,float *y, int N)
{
   int bits=0;
   int i, j, k;
   unsigned pow_bits=0;

   for (i=0; i<MAXPOW; i++)
      if (1 << i==N) bits=i-1;
      for (i=1; i<N; i++)
      {
          j=0;
          unsigned pow_2k=0,pow_2kj;

          for (k=0; k<bits; k++)
          {
             pow_2k = 1<<k;
             pow_2kj = 1<<(bits-k);
             if (i&pow_2k) j+=pow_2kj;
          }
          if (j>i)
          {
             swap(&x[i],&x[j]);
             swap(&y[i],&y[j]);
          }
       }
}

循環數從近50萬個循環減少到約18萬個循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM