简体   繁体   English

这是reinterpret_cast可以做的

[英]Is this reinterpret_cast OK to do

I am a EE, not a code expert, so please bear with me here. 我是EE,而不是代码专家,所以请在这里请耐心等待。

I am using Embarcadero C++ Builder (XE3). 我正在使用Embarcadero C ++ Builder(XE3)。

I have an FFT algorithm which does a fair number of operations on complex numbers. 我有一个FFT算法,它对复数进行了大量的操作。 I found out that if I bypass Embarcadero's complex math library, and do all the calculations in my own code, my FFT will run about 4.5 times faster. 我发现如果我绕过Embarcadero的复杂数学库,并在我自己的代码中进行所有计算,我的FFT运行速度将快4.5倍。 The 4 operations shown here all require an inordinate amount of time. 这里显示的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); 

Replacing the multiplication with my own cross multiply cut my execution times in half. 用我自己的交叉乘法替换乘法将我的执行时间减半。 My concern however is with the way I am accessing the real and imaginary parts of the input array. 然而,我关心的是我访问输入数组的实部和虚部的方式。 I am doing this: 我这样做:

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];

Doing this cut my execution times in half again, but I don't know if this reinterpret_cast is a wise thing to do. 这样做可以将执行时间再缩短一半,但我不知道这种reinterpret_cast是否是明智之举。 I could change the input array to two doubles instead of a complex, but I am using this FFT in numerous programs and don't want to rewrite everything. 我可以将输入数组更改为两个双精度而不是复数,但我在许多程序中使用此FFT并且不想重写所有内容。

Is this reinterpret_cast OK, or will I have memory problems? 这个reinterpret_cast好吗,还是我有内存问题? Also, is there a way to get the Embarcadero complex math functions to run faster? 另外,有没有办法让Embarcadero复杂的数学函数运行得更快? And finally, although its not terribly important to me, is this reinterpret_cast portable? 最后,虽然它对我来说不是非常重要,但是这个reinterpret_cast是否可移植?

This is allowed. 这是允许的。 Whilst this isn't a standard quote, cppreference has this to say: 虽然这不是标准报价,但cppreference有这样的说法:

For any pointer to an element of an array of complex numbers p and any valid array index i , reinterpret_cast<T*>(p)[2*i] is the real part of the complex number p[i] , and reinterpret_cast<T*>(p)[2*i + 1] is the imaginary part of the complex number p[i] . 对于任何指向复数p和任何有效数组索引i的元素的指针, reinterpret_cast<T*>(p)[2*i]是复数p[i]的实部,并且reinterpret_cast<T*>(p)[2*i + 1]是复数p[i]的虚部。

I will look for the quote from the actual standard soon. 我很快就会从实际标准中寻找报价。

From here it says at the bottom of the page: 这里它在页面底部说:

For any complex number z, reinterpret_cast<T(&)[2]>(z)[0] is the real part of z and reinterpret_cast<T(&)[2]>(z)[1] is the imaginary part of z. 对于任何复数z, reinterpret_cast<T(&)[2]>(z)[0]是z的实部,而reinterpret_cast<T(&)[2]>(z)[1]是虚部的虚部。 ž。

For any pointer to an element of an array of complex numbers p and any valid array index i, reinterpret_cast<T*>(p)[2*i] is the real part of the complex number p[i], and reinterpret_cast<T*>(p)[2*i + 1] is the imaginary part of the complex number p[i]. 对于任何指向复数p和任何有效数组索引i的元素的指针, reinterpret_cast<T*>(p)[2*i]是复数p [i]的实部,并且reinterpret_cast<T*>(p)[2*i + 1]是复数p [i]的虚部。 (Since C++11) (自C ++ 11以来)

These requirements essentially limit implementation of each of the three specializations of std::complex to declaring two and only two non-static data members, of type value_type, with the same member access, which hold the real and the imaginary components, respectively. 这些要求实质上限制了std :: complex的三个特化中的每一个的实现,以声明两个且仅有两个类型为value_type的非静态数据成员,它们具有相同的成员访问权限,分别保存实部和虚部。

So what you are doing is guaranteed to work in C++11, but not before that. 所以你所做的就是保证在C ++ 11中工作,但在此之前不行。 It may still work with your library's implementation, but you need to check that your library's implementation does not define any more non-static data members as per the third paragraph. 它可能仍然适用于您的库的实现,但您需要检查您的库的实现没有按照第三段定义任何更多的非静态数据成员。

There is no way we can answer that without having the definition of std::complex you use and knowing how your compiler implement this definition. 如果没有使用std::complex的定义并且知道编译器如何实现这个定义,我们就无法回答这个问题。 Indeed, whether the reinterpret_case is correct or not depend on the memory layout of the std::complex type. 实际上, reinterpret_case是否正确取决于std::complex类型的内存布局。 As far is I know, there is nothing specified here. 据我所知,这里没有任何指定。 So it is certainly not portable. 所以它肯定不便携。 So the answer is: it might work on some compiler/architecture and not on some other. 所以答案是:它可能适用于某些编译器/架构,而不适用于其他一些编译器/架构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM