[英]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.