chili
chili

Reputation: 676

Concurrency with std::vector<>::size()

This code hangs (only in Release build, mind you) and must be terminated manually:

#include <Windows.h>
#include <vector>
#include <thread>

int main()
{
    std::vector<int> vec;
    vec.push_back( 0 );
    std::thread( [&vec]()
    {
        Sleep( 150 );
        vec.pop_back();
    } ).detach();
    while( vec.size() > 0 );
    return 0;
}

Whereas this code terminates naturally:

#include <Windows.h>
#include <vector>
#include <thread>

int main()
{
    std::vector<int> vec;
    vec.push_back( 0 );
    std::thread( [&vec]()
    {
        Sleep( 150 );
        vec.pop_back();
    } ).detach();
    while( vec.size() > 0 )
    {
        Sleep( 1 );
    }
    return 0;
}

It seems that continuous spamming of std::vector<int>::size() is blocking execution somehow, but how and why? And why only in Release build?

(Built with VC2013, if that is a factor.)

Upvotes: 1

Views: 241

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126203

The most likely explanation is that the optimizer turns the loop:

while (vec.size() > 0);

into

reg = vec.size(); while(reg > 0);

...loading the value from vec.size() into a register and just reading it from there, since there is nothing in the loop that indicates a memory barrier that might cause the value to be changeable.

When you put a Sleep call in the loop, the call involves spilling registers, so saving the value in the register provides no benefit, so isn't done.

Upvotes: 3

aho
aho

Reputation: 314

The hanging code's problem is

while (vec.size() > 0);

which is the same as:

while (vec.size() > 0)
{
}

this is a tight loop continuously calling the same thing - your processor is repeatedly calling this method without doing anything else.

However, this:

while (vec.size() > 0) Sleep(1);

is telling the processor to do nothing for a millisecond (i.e. it's taking a break, likely allowing another process to run on this core in the meantime), and then calls the method again.

It's like you running as fast as you can in a non-stop sprint (hanging code), versus sprinting for a bit, then taking a moment to rest, then sprinting again, etc (non-hanging)

Upvotes: 1

Related Questions