Search code examples
c++optimizationstdvectorlapackblas

Fastest way to negate a std::vector


Assume I have a std::vector of double, namely

std::vector<double> MyVec(N);

Where N is so big that performance matters. Now assume that MyVec is a nontrivial vector (i.e. it is not a vector of zeros, but has been modified by some routine). Now, I need the negated version of the vector: I need -MyVec.

So far, I have been implementing it via

std::transform(MyVec.cbegin(),MyVec.cend(),MyVec.begin(),std::negate<double>());

But, really, I do not know if this is something sensible or it is just super naïve from my side.

Am I doing it correctly? Or std::transform is just a super slow routine in this case?

PS: I am using BLAS and LAPACK libraries all the time, but I have not found anything that matches this particular need. However, if there exists such a function in BLAS/LAPACK which is faster than std::transform, I would be glad to know.


Solution

  • #include <vector>
    #include <algorithm>
    #include <functional> 
    void check()
    {
        std::vector<double> MyVec(255);
        std::transform(MyVec.cbegin(),MyVec.cend(),MyVec.begin(),std::negate<double>());
    }
    

    This code on https://godbolt.org/ with copile option -O3 generate nice assembly

    .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:
    

    It's difficult to imagine faster. Your code is already perfect, don't try to outsmart the compiler and use clean C++ code it works almost every times.