just::thread Support Forum

General Category => General Discussion about just::thread => Topic started by: Kenneth Carter on November 25, 2008, 01:55:35 AM

Title: is it possible to tell a thread to wait without using a lock
Post by: Kenneth Carter on November 25, 2008, 01:55:35 AM
I am not sure if I understand the unique_lock very well. I have this scenerio with the MT algorithm.

I have determined that there is no gain to the algorithm if the generate method has to initialize the threads every time before twisting the array[ 624 ].

I am taking an approach were the contructor creates the threads at the time that the CRandomMT is instantiated. I assign a block of the array to each thread. then I want each thread to stay running for the lifetime of the CRandomMT random number generator. I also want the threads to wait until I queue them to twist there block of the array. then once they are done wait again until they are queued to do it again.

each block of the array is isolated from another block of the array.

does a unique_lock provide this functionality or does it behave differently?

Kenneth
Title: Re: is it possible to tell a thread to wait without using a lock
Post by: Anthony Williams on November 25, 2008, 08:12:48 AM
I am not sure if I understand the unique_lock very well. I have this scenerio with the MT algorithm.

I have determined that there is no gain to the algorithm if the generate method has to initialize the threads every time before twisting the array[ 624 ].

I am taking an approach were the contructor creates the threads at the time that the CRandomMT is instantiated. I assign a block of the array to each thread. then I want each thread to stay running for the lifetime of the CRandomMT random number generator. I also want the threads to wait until I queue them to twist there block of the array. then once they are done wait again until they are queued to do it again.

each block of the array is isolated from another block of the array.

does a unique_lock provide this functionality or does it behave differently?

Just to recap: you want the threads to wait for some condition (you want the threads to twist their block of the array), perform their operation and then resume waiting on the condition.

That sounds like a job for a condition variable:

Code: [Select]
std::condition_variable cond;
std::mutex m;
bool do_twist=false;
bool done_twist=false;

void twister_thread(char* array_block_start)
{
    for(;;)
    {
        std::unique_lock<std::mutex> ul(m);
        done_twist=false;
        while(!do_twist)
            cond.wait(ul);
        ul.unlock(); // we don't need to hold the lock whilst we do the twist
        do_twist(array_block_start);
        ul.lock(); // lock the mutex again
        done_twist=true;
    }
}

The controlling thread can then lock the mutex, set do_twist to true and call cond.notify_one() to wake the twisting thread. If you have multiple twisting threads and you want them all to process together, use the same condition variable for all of them and call cond.notify_all() to wake all of them.
Title: Re: is it possible to tell a thread to wait without using a lock
Post by: Kenneth Carter on November 25, 2008, 05:57:39 PM
well, I have done it. I have a bench mark on using concurrency with how just::thread can effect how the Mersienne Twister psuedorandom number generator can benefit from multi threading.

the the application is running in debug on vista ultimate x64 on a AMD Athlon 64 x2 Dual core 4200+ clocked at 2.21 ghz with 4 GB Ram.

the first concurrency test runs using 4 threads to simulate the ~performance of an x4 processor though I expect the results to be better. then I disable concurrency which shuts down the extra threads and only leaves the main thread of execution. then I re-enable the threaded execution which creates threads of execution based on hardware concurrency which is 2 on my computer.

here are the results:

generating 20,000,000 random numbers using hardware concurrency!
plus two threads simulate x4 core processor.

2.23366 seconds

generating 20,000,000 random numbers using main thread of execution!

2.45851 seconds

generating 20,000,000 random numbers using hardware concurrency!

2.42844 seconds

generating 20,000,000 random numbers using main thread of execution!

2.42402 seconds

generating 20,000,000 random numbers using hardware concurrency!

2.30001 seconds

generating 20,000,000 random numbers using main thread of execution!

2.43711 seconds

generating 20,000,000 random numbers using hardware concurrency!

2.35871 seconds

as you notice in the above sample the main thread of execution out performed the threaded only once out of all the iterations of generating 20 million random numbers. the majority of the time the threaded implementation of the random number generator out performed the syncronous version of the algorithm.

Kenneth

P.S. Anthony your advice on how to handle the thread control was key in getting this performance. though I am not using a while loop to control the wait. I use an if statement because the only time the threads will ever wake up is when a call is made to generate();