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
<
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.
It can, and it's a shame that it usually doesn't. At the very least it would mean an improvement to code size. The problem is that while it's easy enough for a human to spot a memset, there's a huge amount of temporary objects and other cruft generated by that one line, and it's not so easy to optimize.
The shame is that the simple loop is generated because it does at least simplify down to something like:
const T val(0.0);
for (size_t i = 0; i < 30000; ++i) vec.data[i] = double(val);
...but it doesn't make the final deductive leap that a 0..30000 loop through an array of pod types being initialized to the same value is best done with a memset. As mentioned by wilhelmtell, some implementations specialize on a few pod types where there's a large win (looping on chars is slow). I really do wish compilers would make that final leap because it would help uptake of using container libraries in general if people knew this won't happen.
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
.