This is reinterpret_cast OK to do

I am an EE, not a code expert, so please carry me here.

I am using Embarcadero C ++ Builder (XE3).

I have an FFT algorithm that performs many operations on complex numbers. I found out that if I go around the complex Embarcadero math library and do all the calculations in my own code, my FFT will work about 4.5 times faster. All 4 operations shown here require an excessive amount of time.

#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 multiplication with my own cross doubles the execution time. However, my concern is with the way I access the real and imaginary parts of the input array. I'm doing it:

 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 reduction in execution time in half again, but I don't know if this reinterpret_cast is reasonable. I can change the input array to two doubles instead of a complex one, but I use this FFT in numerous programs and do not want to rewrite everything.

Is it reinterpret_cast OK, or will I have memory problems? Also, is there a way to make Embarcadero's math functions work faster? And finally, although this is not very important to me, is it portable reinterpret_cast?

+6
source share
3 answers

It is allowed. Although this is not a standard quote, cppreference has this to say:

For any pointer to an element of the array of complex numbers p and any real index of the array 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] - the imaginary part of the complex number p[i] .

In the near future I will look for a quote from the actual standard.

+4
source

From here, he 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.

For any pointer to an element of the array of complex numbers p and any real index of the array 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]. (Since C ++ 11)

These requirements significantly limit the implementation of each of the three specializations std :: complex for declaring two and two non-static data elements of type value_type with the same member access, which contain real and imaginary components, respectively.

So, what you do is guaranteed to work in C ++ 11, but not earlier than that. It may still work with your library implementation, but you need to check that your library implementation no longer defines non-static data elements according to the third paragraph.

+2
source

It is impossible to answer this question without using the definition of std::complex and not knowing how your compiler implements this definition. Indeed, whether or not reinterpret_case depends on a memory layout of type std::complex correct. As far as I know, nothing is indicated here. So this, of course, is not portable. Therefore, the answer: it can work on some compilers / architectures, and not on some others.

0
source

Source: https://habr.com/ru/post/955680/


All Articles