fftw manual指出 ( Page 4 )
The data is an array of type fftw_complex, which is by default a
double[2]
composed of the real (in[i][0]
) and imaginary (in[i][1]
) parts of a complex number.
对于 n
个样本的时间序列进行 FFT,矩阵的大小变为 n
行和 2 列。如果我们希望逐个元素地进行操作,访问 in[i][0]
是否不会因为 i
的不同值而对较大的 值变慢n
因为 C 以行优先格式存储二维数组?
最佳答案
实部和虚部连续存储在内存中(假设小端布局,其中 R0 的字节 0 位于最小地址):
In-1,Rn-1..|I1,R1|I0,R0
这意味着可以将元素 i 复制到访问相同缓存行(如今通常为 64 字节)的位置,因为实数和虚数都是相邻的。如果您以 Fortan 顺序存储二维数组并想分配给一个元素,那么您会立即访问 2 个不同缓存行上的内存,因为它们在内存中分开存储 N*sizeof 双倍位置 - Row & COlumn Major order
现在,如果您的处理只是在一个线程中对实部进行操作,而在另一个线程中单独对虚部进行操作,出于某种原因,那么是的,将它们存储在列主顺序中甚至作为单独的并行数组会更有效。不过,一般来说,数据存储在一起是因为它们是一起使用的。
C 中的所有数组实际上都是一维字节数组,除非您存储指向数组的指针数组,通常使用不同长度的字符串来完成。
有时在矩阵计算中,首先转置一个数组实际上更快,因为矩阵乘法的规则,它很复杂,但如果你想要真正的细节,请搜索 LWN.net 上关于内存的 Ulrich Dreppers 文章,它显示了一个受益于此技术的示例(第 5 节 IIRC)。
科学数字库通常按列主要顺序工作,因为 Fortran 兼容性比以自然方式使用数组更重要。大多数语言更喜欢 Row major,因为它通常更可取,例如,当您在表中存储固定长度的字符串时。
关于c - 为什么在 fftw 中按行声明复数数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24687869/