Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::fill does not turn into memset for POD types

Tags:

c++

I am expecting a std::fill on an continuous container, say std::vector, will automatically compiled to a call of memset. However, when I tried the following code

#include <vector>
#include <algorithm>
#include <numeric>

using namespace std;

int main()
{
    vector<double> vec(300000);

    fill(vec.begin(),vec.end(),0.0);

    memset(&vec[0],0,vec.size()*sizeof(double));
}

gcc compiled the first std::fill to a simple loop. But I think it could be done by SSE or other advanced vectorized code. Please give me a hint. Thanks.

like image 221
xis Avatar asked Feb 22 '11 05:02

xis


People also ask

Is memset faster than fill?

memset can be faster since it is written in assembler, whereas std::fill is a template function which simply does a loop internally.

What can I use instead of memset?

There isn't a standard function for this - you will just need to call memcpy() in a loop: my_stuff *my_array = malloc(MAX * sizeof(my_stuff)); my_stuff tmp; size_t i; tmp.

Can I use memset with vector?

Explanation: The memset() in C++ can be used for vectors as mentioned above.

Is std :: array pod?

In C++03, POD was defined in terms of aggregate: a class where every subobject is native or an aggregate is POD. So, by backwards compatibility, a C++0x std::array is POD.


2 Answers

Addressing your specific example of double, it would have to be a platform specific optimization and most likely g++ decided not to do such a thing. The reason is of course any platforms using a representation of double for which 0.0 does not mean all zero bytes. Note that additionally, setting to any number OTHER than zero is a whole different game as it's not just setting every byte to zero: There is a specific pattern that needs to be followed. It gets worse with negative numbers.

Unless you have specific profiling information that the fill is taking significantly longer than memset I wouldn't be too worried about it. If it IS taking a lot longer you can either hand-tune to manually use memset or try to address the root cause, the need to set to zero repeatedly.

like image 85
Mark B Avatar answered Nov 15 '22 11:11

Mark B


The standard doesn't force implementors to use memset(). But gcc for example does happen to use memset() for std::fill() on containers of char.

like image 36
wilhelmtell Avatar answered Nov 15 '22 11:11

wilhelmtell