c - 为什么在 fftw 中按行声明复数数组?

标签 c arrays fftw

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/

相关文章:

c - 寻找我参加的旧测试的答案,试图了解我应该做什么。(也许是 Malloc 函数?)

从结构体创建对象列表

c - 如何将数字添加到字符串的每个字符

java - 在 Java 中声明全局 arrayList

image-processing - 我在哪里可以找到解释 FFT 相位相关评分的良好信息来源

c - 意外的结果 - 寻找最大值和第二最大值

javascript - 推送到 React 状态数组

ruby - 如何从 Ruby 中的多维数组中检索值?

fftw - fftw 输出取决于输入的大小吗?

image-processing - 二维 FFTW 帮助