7

我是 EE,不是代码专家,所以请多多包涵。

我正在使用 Embarcadero C++ Builder (XE3)。

我有一个 FFT 算法,它可以对复数进行大量操作。我发现如果我绕过 Embarcadero 的复杂数学库,并在我自己的代码中进行所有计算,我的 FFT 将运行大约 4.5 倍的速度。此处显示的 4 个操作都需要过多的时间。

#include <dinkumware\complex>
#define ComplexD std::complex<double>
ComplexD X, Y, Z, FFTInput[1024];
double x, y;
Z = X * Y; 
x = X.real();
y = X.imag();
Z = ComplexD(x,y); 

用我自己的交叉乘法替换乘法将我的执行时间减半。然而,我担心的是我访问输入数组的实部和虚部的方式。我正在这样做:

double *Input;
Input = reinterpret_cast<double *>(FFTInput);
// Then these statements are equivalent.
x = FFTInput[n].real();
y = FFTInput[n].imag();
x = Input[2*n];
y = Input[2*n+1];

这样做又将我的执行时间缩短了一半,但我不知道这个 reinterpret_cast 是否是明智之举。我可以将输入数组更改为两个双精度而不是一个复数,但是我在许多程序中都使用了这个 FFT,并且不想重写所有内容。

这个 reinterpret_cast 可以吗,还是我会有内存问题?另外,有没有办法让 Embarcadero 复杂的数学函数运行得更快?最后,虽然它对我来说不是很重要,但这个 reinterpret_cast 是否可移植?

4

2 回答 2

5

这是允许的。虽然这不是标准报价,但cppreference有这样的说法:

对于任何指向复数数组元素的指针p和任何有效的数组索引ireinterpret_cast<T*>(p)[2*i]都是复数的实部,是复数p[i]reinterpret_cast<T*>(p)[2*i + 1]虚部p[i]

我会尽快从实际标准中寻找报价。

于 2013-10-10T15:38:28.200 回答
2

这里开始,它在页面底部显示:

对于任何复数 z,reinterpret_cast<T(&)[2]>(z)[0]是 z 的实部, 是 zreinterpret_cast<T(&)[2]>(z)[1]的虚部。

对于任何指向复数数组元素 p 和任何有效数组索引 i 的指针,reinterpret_cast<T*>(p)[2*i]是复数 p[i] 的实部,是复数 p[i]reinterpret_cast<T*>(p)[2*i + 1]的虚部。(C++11 起)

这些要求实质上将 std::complex 的三个特化中的每一个的实现限制为声明两个且仅两个非静态数据成员,类型为 value_type,具有相同的成员访问权限,分别保存实部和虚部。

所以你所做的保证可以在 C++11 中工作,但在此之前不能。它可能仍然适用于您的库的实现,但您需要检查您的库的实现是否没有根据第三段定义任何更多的非静态数据成员。

于 2013-10-10T15:39:51.153 回答