我目前正在尝试最有效地对一个复数数组(内存对齐方式与 std::complex 相同,但当前使用我们自己的 ADT)与一个相同的标量值数组进行就地乘法大小为复数数组。
该算法已经并行化,即调用对象将工作拆分为线程。此计算是在数以亿计的数组上完成的 - 因此,可能需要一些时间才能完成。CUDA 不是该产品的解决方案,尽管我希望它是。我确实可以使用 boost,因此有一些使用 BLAS/uBLAS 的潜力。
但是,我认为 SIMD 可能会产生更好的结果,但我对如何使用复数执行此操作还不够熟悉。我现在拥有的代码如下(请记住,这被分成与目标机器上的内核数相对应的线程)。目标机器也是未知的。因此,通用方法可能是最好的。
void cmult_scalar_inplace(fcomplex *values, const int start, const int end, const float *scalar)
{
for (register int idx = start; idx < end; ++idx)
{
values[idx].real *= scalar[idx];
values[idx].imag *= scalar[idx];
}
}
fcomplex 定义如下:
struct fcomplex
{
float real;
float imag;
};
我已经尝试手动展开循环,因为我的 finally 循环计数将始终是 2 的幂,但是编译器已经为我这样做了(我已经展开到 32)。我已经尝试了对标量的 const float 引用——我认为我会保存一次访问——事实证明这等于编译器已经在做的事情。我已经尝试过 STL 和变换,哪个游戏接近结果,但仍然更糟。我也尝试过强制转换为 std::complex 并允许它使用重载运算符进行 scalar * complex 进行乘法运算,但这最终产生了相同的结果。
那么,有任何想法的人吗?非常感谢您花时间考虑这一点!目标平台是 Windows。我使用的是 Visual Studio 2008。产品也不能包含 GPL 代码!非常感谢。