最快的方式复制一维二维矢量在c++
Fastest way to copy one dimension of 2D vector in c++
我有一个用于复数的2D向量。例如:
vector<vector<double>> Complex;
vector<double> ComplexNumber;
ComplexNumber.push_back(5); // real part
ComplexNumber.push_back(-4); // imag part
Complex.push_back(ComplexNumber); // Complex[i][0] - real part, [i][1] - imag
在我的代码的深度,我需要拉出我的复杂向量的一部分到其他。例如,将索引10的实部复制到某个变量(1D向量)中的实部,并将索引10的映像部分复制到其他变量(1D向量)中的实部。目前我正在使用for循环:
for (int j=0; j<=Samples; j++)
{
refRealSignal[j] = ReferenseComplexSignalsSampled[(i*SignalSampleIndex)+j][0] ;
refImagSignal[j] = ReferenseComplexSignalsSampled[(i*SignalSampleIndex)+j][1] ;
}
如profiler所示,这段代码是整个程序的瓶颈。有什么办法可以改进吗?
小更新: "Sample"变量是8到20的int
,通常是8。变量i
来自外部for循环。
大更新:所以,我把2D向量和重写的一切与complex
类。我也重写了我的多操作在"for"循环。我不知道为什么,但是从complex.imag
复制比从complex.real
部分复制需要更多的时间(多2)。在所有这些之后,代码的性能从一个样本的~5 ms增加到一个样本的~1.8 ms。(2.5毫秒后,我重写多操作,也重写整个周期,这是一个非常有用的建议,非常感谢)
如果Samples
较大,则可以节省有关i
的一些乘法。所以修改这个:
for (int j=0; j<=Samples; j++)
{
refRealSignal[j] = ReferenseComplexSignalsSampled[(i*SignalSampleIndex)+j][0] ;
refImagSignal[j] = ReferenseComplexSignalsSampled[(i*SignalSampleIndex)+j][1] ;
}
:
int index;
for(i = ..) { // assuming your code has a for loop for i
index = i*SignalSampleIndex;
for (int j=0; j<=Samples; ++j) // change the ++ as pre-fix
{
refRealSignal[j] = ReferenseComplexSignalsSampled[index+j][0] ;
refImagSignal[j] = ReferenseComplexSignalsSampled[index+j][1] ;
}
}
这样你就做了1次乘法,而不是像luk32注意到的那样做2 * Samples
。
另一种方法,如评论中所讨论的,您可以使用类来表示您的复数。STL
提供了一个类:std::complex
.
那么你将有一个类型为std::complex
的vector
,这将使你的数据更健壮,这可能会改进locality
, caching
将利用它。
你可以这样做:
#include <iostream> // std::cout
#include <complex> // std::complex, std::real
#include <vector> // std::vector
int main ()
{
std::vector<std::complex<double> >complex;
// if you know the amount of your numbers,
// use a reserve(). Assuming you will insert
// 100000 numbers, the code would be
complex.reserve(100000);
for(int i = 0; i < 100000; ++i)
complex[i] = {0.1, 0.2};
std::cout << "Real part of 1st element: " << std::real(complex[0]) << 'n';
return 0;
}
[编辑]通过使用优化标志,可以由编译器执行乘法问题。在编译代码时,请确保使用优化标志对代码进行了配置。
提示:
通常如果某个部分减慢了程序的速度,有两种方法:(1)使该部分更快,或者(2)找到一种方法减少该部分的执行次数。
(归功于Psyduck, aka Mooling duck)
在你的情况下,你可以尝试我上面的建议,使你的代码更快,但如果你会再次思考你的逻辑,避免/减少你复制的时间,那么将获得一个提升性能的奖励。
对复数使用std::vector<double>
是一个巨大的错误。表演为什么?原因如下:
-
分配是永久的。典型值在200ns以上。
-
内存在堆上分配。空间开销是巨大的。
-
内存分配器内的典型开销:两个指针,即8或16字节,具体取决于您的体系结构。
-
std::vector<>
本身的开销:两个指针,另一个8或16字节。 -
std::vector<>
的过度分配:典型的实现从不为两个元素分配内存。我估计这个开销至少 6个元素(最小分配8个元素)。这将导致48字节的开销。
所以,你最终使用了80字节来存储16个字节的内容。
这很重要,因为这意味着你的缓存/内存总线必须做五倍的工作!
-
-
内存在堆上分配。这意味着你的复数很可能是分散的。这是对缓存效率的又一次打击。
如果你想要更快,使用两个元素的数组(不管你是使用C风格的数组还是c++ std::array<>
),或者将你的复杂类型定义为一个普通的旧数据struct
。所有三个选项都具有相同的内存布局,因此在性能上应该是相等的。但我更喜欢struct
方法,因为它允许您重载运算符,这对于复数,向量,四元数等数学类型非常好。
- 将二维矢量传递给类
- 将值从二维数组输出到文本文件
- 我在二维向量中是否正确分配了内存
- 带结构的二维矢量:如何存储元素
- 在二维数组中查找最小值和最大值?
- 移动二维数组中的字符
- C++ 传递二维字符数组
- 如何正确填充在堆上分配的二维数组?
- 传递二维数组时出现问题
- 具有随机数的二维数组不会更改
- 如何在C++中获取二维数组中最少的一列数?
- 如何使用用户输入变量制作二维数组?
- C++ 中的二维整数数组,每行中的元素数量不均匀
- C++ 中动态二维数组的访问冲突
- 在二维向量或数组中可以存储的最大元素数是多少?
- 如何将整数字符串转换为整数的二维向量?
- 二维矢量数据成员
- 遍历二维数组的所有子数组
- 将二维数组的所有元素插入到一维数组中
- 在函数中传递二维数组