【发布时间】:2016-11-10 14:28:56
【问题描述】:
前段时间,我使用 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 条指令向量可用于交换循环?
【问题讨论】:
-
我可能是错的,但我认为
bit_reverse_reorder函数正在执行 FFT 的 butterfly reordering 步骤。如果你对 FFT 的那一步不太了解,那么很难优化这个函数。 -
位反转重新排序很可能是您执行配置文件中相当微不足道的部分 - 您是否实际测量/分析它以查看是否值得进一步优化?请记住,FFT 本身是
O(n log n),而您的位反转阶段只是O(n)- 除非n非常小,否则它不应该成为性能瓶颈。 -
即使在 AES 解压缩等经常使用此类东西的情况下,这一步也可能不是您最大的打击。如果是的话,看看那里的各种 AES-128 解压缩器 (openSSL),你将有一个如何在 Intel 中执行此操作的示例。
-
看看my answer 我上面链接的问题。它不使用 SIMD 指令,所以我决定将我的答案添加到更一般的问题中。无论如何,SIMD 可能对您没有帮助,除非如果您交错
x和y数组,可能会一次性交换元素。如果MAXPOW是静态的,或者如果您多次执行 FFT,最好的方法可能是预先计算要交换的索引。
标签: c optimization simd