ena*_*one 26 c++ optimization blas stdvector lapack
假设我有一个double的std :: vector,即
std::vector<double> MyVec(N);
Run Code Online (Sandbox Code Playgroud)
在哪里N
这么大,性能很重要.现在假设这MyVec
是一个非平凡的向量(即它不是一个零向量,但已被某些例程修改).现在,我需要向量的否定版本:我需要-MyVec
.
到目前为止,我一直在实施它
std::transform(MyVec.cbegin(),MyVec.cend(),MyVec.begin(),std::negate<double>());
Run Code Online (Sandbox Code Playgroud)
但是,实际上,我不知道这是否合情合理,或者只是我身边的超级天真.
我做得对吗?或者std :: transform在这种情况下只是一个超级慢的例程?
PS:我一直在使用BLAS和LAPACK库,但是我没有发现任何符合这种特殊需求的东西.但是,如果BLAS/LAPACK中存在比std :: transform更快的函数,我很高兴知道.
Col*_*Cat 28
#include <vector>
#include <algorithm>
#include <functional>
void check()
{
std::vector<double> MyVec(255);
std::transform(MyVec.cbegin(),MyVec.cend(),MyVec.begin(),std::negate<double>());
}
Run Code Online (Sandbox Code Playgroud)
这个代码在https://godbolt.org/上,带有copile选项-O3,可以生成很好的程序集
.L3:
[...]
cmp r8, 254
je .L4
movsd xmm0, QWORD PTR [rdi+2032]
xorpd xmm0, XMMWORD PTR .LC0[rip]
movsd QWORD PTR [rdi+2032], xmm0
.L4:
Run Code Online (Sandbox Code Playgroud)
很难想象更快.你的代码已经完美了,不要试图超越编译器并使用几乎每次都能运行的干净的C++代码.
kei*_*ith 17
幸运的是,数据std::vector
是连续的,所以你可以使用向量内在函数乘以-1(使用未对齐的加载/存储和特殊处理可能的溢出).或者使用ippsMulC_64f
/ ippsMulC_64f_I
来自intel的IPP库(你很难写出更快的东西),它将使用你平台上最大的矢量寄存器:https://software.intel.com/en-us/ipp-dev-reference-mulc
更新:为了澄清评论中的一些混淆,英特尔IPP的完整版本是免费的(虽然你可以支付支持),并且来自Linux,Windows和macOS.
归档时间: |
|
查看次数: |
3335 次 |
最近记录: |