Thread: Inconsistent (and wrong) output using boost::thread

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    2

    Inconsistent (and wrong) output using boost::thread

    Alright, I'm trying to learn some basic threading and this is a problem I've been banging my head up against for a while.
    I'm doing some image manipulation using boost::numeric::ublas::matrix, which I believe is supposed to be thread safe, but as soon as more than 1 concurrent thread is involved I get radically different results on every execution.
    I believe my algorithms should be order independent (or close to it).

    My first bit of calling code looks like:
    Code:
    do
    {
    
    	n = 0;
    	
    	
    	for (int structNum = 0; structNum < 8; structNum++)
    	{
    		for (int x = 0; x < numthreads; x++)
    		{
    			
    			tg.create_thread(boost::bind(&decompose::octagon,d,boost::ref(M),boost::ref(copy),x,structNum, boost::ref(n), boost::ref(bar)));
    		}
    		//d->octagon(M,copy,0,structNum,n);
    		
    		bar.wait();
    		
    		tg.join_all();
    		
    		
    		d->copy(copy,M);
    
    	}
    	if (n == 0)
    		break;
    	numLoops ++;
    
    }while(n);
    And it's calling:
    Code:
    void decompose::octagon(matrix4D &M, matrix4D &copy, int threadNum, int structNum, int &n, boost::barrier &bar)
    I have two copies of my matrices, an original and a copy. For each call to octagon, the original is only used as read only while the copy has its corresponding values modified. I send the function what thread number this is (a global variable stores the number of threads) and the general algorithm through the matrix is:
    Code:
    	for (x = threadNum; x < (h); x += num)
    	{
    		for (y = threadNum; y < (w); y+= num)
    Where threadnum is the current thread number, and num is the total number of concurrent threads. As such, no threads should ever operate on the same element in the matrix object (unless I'm wrong about matrix being thread safe).

    I expected tg.join_all() to cause each thread to finish execution before program flow would continue. I wasn't sure if it wasn't doing that, so I tried adding a barrier condition (bar) with a count of 3, though that doesn't seem to make a difference. Still, each thread calls bar.wait() upon finishing, and so does main after creating both threads. Also, join_all doesn't seem to destroy threads, so threadgroup tg ends up containing hundreds of threads by the end of the program execution. I assume that they're mostly all just idle, but I suppose it could be a problem.

    Am I missing something major with my threading design?

  2. #2
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    1. As you indicated, the barrier is not necessary.
    2. You could put the thread group inside of the loop so that it is destroyed after each round.
    3. Unfortunately, I don't know the answer to your question.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  3. #3
    Registered User
    Join Date
    Dec 2008
    Posts
    2
    Actually, I figured it out. I had already debugged a lot of problems, but had two major ones left.
    One was that one of the algorithms just wasn't suited to multithreading.
    The other problem was that the rest of the algorithms were implemented incorrectly, so they would fail only under the case of multithreading. Basically, I never reached all the elements in the matrix.

Popular pages Recent additions subscribe to a feed