Results 1 to 14 of 14

Thread: update progressBar in parallel loop, using OpenMP

  1. #1
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default update progressBar in parallel loop, using OpenMP

    Hello,

    I have subclassed a Qthread to do some work, and I also wanted to update a progressbar value.

    for that, i have done this:

    Qt Code:
    1. #pragma omp parallel for private(...) firstprivate(...) reduction(+:progressValue)
    2. for (int i =0 ; i< n ; i++)
    3. {
    4. ....
    5. ......
    6. for (int j = 0 ; j <n; j++)
    7. {
    8. mLoack.lock();
    9. access vector[j];
    10. mLoack.unlock();
    11. .......
    12. .......
    13. } // forj
    14. #pragma omp atomic
    15. progressValue +=1;
    16.  
    17. emit updateProgressbarValue(progressValue);
    18. }
    To copy to clipboard, switch view to plain text mode 

    This loop in a the mythread, I emit a signale to update the progressebar.

    but when i run it, the progressbar keep plinking and just reach to 12% only.

    can anyone please tell me how can i update the progressBar value in parallel loop.

    Thank you so much.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    Where is this code located?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default Re: update progressBar in parallel loop, using OpenMP

    In a separate thread. I emit the signal and i connect it to a slot in the main thread.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    So you have a QThread and somewhere in its run() implementation you start a bunch of other threads using OpenMP and the code you posted is inside this MP block?

    Can we see the exact code?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default Re: update progressBar in parallel loop, using OpenMP

    Yes, this is the case. as you can see i do have the OpemMP pragma with the code i posted. this OpenMP pragma will fork threads based on your how many cores the machine has. in my case they are 8.

    Qt Code:
    1. // in the main thread
    2.  
    3. mythead threadCompute = new compute(VecotrA,VecotrB);
    4. connect(threadCompute,SIGNAL(updateProgressbarValue(int)),this,SLOT(onUpdateProgressBarValue(int)));
    5.  
    6. void myClass::onUpdateProgressBarValue(int value)
    7. {
    8. ui->ProgressBar->setValue(value);
    9. }
    10.  
    11. void myClass::computeVectorA()
    12. {
    13. threadCompute->start();
    14. }
    15.  
    16. ///in the QThread ,
    17.  
    18.  
    19. //header
    20. SIGNAL:
    21. void updateProgressbarValue(int value);
    22.  
    23. //cpp
    24. void myThread::run()
    25. {
    26.  
    27. compute();
    28. }
    29.  
    30. void compute()
    31. {
    32. #pragma omp parallel for private(...) firstprivate(...) reduction(+:progressValue)
    33. for (int i =0 ; i < n ; i++)
    34. {
    35. for (int j = 0 ; j <n; j++)
    36. {
    37. updateVectorAat( i ,VecrtorB.at(i));
    38.  
    39. } // forj
    40.  
    41. #pragma omp atomic
    42. progressValue +=1;
    43.  
    44. emit updateProgressbarValue(progressValue);
    45. }
    46.  
    47. }
    To copy to clipboard, switch view to plain text mode 


    this is almost what i am doing, I have not problem with the computation actually, only with updating the progressBar.

    thanks

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    Is progressValue incremented properly for you reaching the expected value?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default Re: update progressBar in parallel loop, using OpenMP

    Actually this is was my problem .. so was hoping that someone has tried that before.

    I solved the problem by removing the "progressValue" from the reduction clause, and just use the atmoic pragma.



    .. so when i create the thread >> new myThread (....), does that mean .. this thread is created and will not be used by the system ?? or its will be mine just when it has work to do ?? only. I mean it only be mine when i called "Qthread.start()".


    Thank you.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    A thread is a thread. It's not "yours" or "anyone else's". A thread belongs to the process and each process has its own set of threads. All threads in the system share the processor -- at some moment a thread from process A can use the CPU but a moment later a thread from a different process might use the same CPU.

    As a side note, I think in your particular case there are no benefits from using multiple threads. I don't know how exactly OpenMP works so I can't say what the compiler will do to your code however a for loop working on the same data in each iteration can't really be parallelized that much.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:

    jesse_mark (23rd January 2013)

  10. #9
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default Re: update progressBar in parallel loop, using OpenMP

    OpenMP will just divide the outer loop, on the number of threads threads.
    so if there is no dependencies between i =1 and i =2, then i=1 and i=2 can be each given to different threads to run them in parallel.
    ex.
    if we have a loop from 1 to 100 and all the logic in this loop has no dependence between different iterations ,then we can safely run i =1 or i = 100 which first does not affect the result. in such cases we can use OpenMP.
    if we assume we have 5 threads then each 20 iteration are given to one thread and execute them in parallel. our loop will become groups of (20, 20 ,20 ,20,20) each group will be run by a thread in the same time.

    maybe you are right, i am new to parallel programming tho.
    but my case is that, i am working on two QVectors, each vector is could be over 1M elements , and holds a strut for each element.

    first vecrtorA has (iD,point,value)
    2nd vectorB has (point, value)
    all what I am trying to do is :

    for each point in VectorA, trying to find the closest point to it in vectorB. If IU find one i take the valaue of that point to assinge it to vectorA not tht value of vectorA for that point will be -1


    Qt Code:
    1. QVector<mystruct1> vectorA;
    2. QVector<mystruct1> vectorB;
    3.  
    4. laodVecotrA(); // vlaue is empty now.
    5. loadVectorB()
    6. /////////////////////////////////////////////
    7.  
    8. mystrcut1 instanceOfMyStruct1;
    9. mystrcut2 instanceOfMyStruct2;
    10. progressValue = 0;
    11.  
    12. #pragma omp parallel for private (mystrcut1,mystrcut2)
    13. for (int i = 0 < i < vectorA.size();i++) // vectorA.size() > 1M
    14. {
    15. instanceOfMyStruct1 = vectorA.at(i);
    16. bool found = false;
    17.  
    18. for(int j = 0 ; j < vectorB.size(); j ++ ) // vectorB.size() > 1M
    19. {
    20. instanceOfMyStruct2 = vectorB.at(j);
    21. found = finedClosestPoint(instanceOfMyStruct1.point , instanceOfMyStruct2.point);
    22. if (found)
    23. {
    24. break ;
    25. }
    26.  
    27. }//for j
    28.  
    29. if (found)
    30. {
    31. instanceOfMyStruct1.value = instanceOfMyStruct2.value ;
    32. vectorA[ i ] = instanceOfMyStruct1;
    33.  
    34. }
    35. else
    36. {
    37. instanceOfMyStruct1.value = -1
    38. vectorA[ i ] = instanceOfMyStruct1;
    39. }
    40.  
    41. #pragma omp atomic
    42. progressValue++;
    43.  
    44. emit updateProgressbarValue(progressValue);
    45. }
    To copy to clipboard, switch view to plain text mode 

    any suggestion in doing that in a better way is really appreciated.

    thank you so much for your time and your help
    Last edited by jesse_mark; 23rd January 2013 at 16:55.

  11. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    Quote Originally Posted by jesse_mark View Post
    so if there is no dependencies between i =1 and i =2, then i=1 and i=2 can be each given to different threads to run them in parallel.
    There is a dependency on j.

    any suggestion in doing that in a better way is really appreciated.
    I think your algorithm is too naive. I think it is possible to come up with an algorithm that makes use of already calculated results to cut off calculations for further input. I think doing some clustering before trying to find neighbours should give a large increase in speed. It's just a thought though.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #11
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default Re: update progressBar in parallel loop, using OpenMP

    There is a dependency on j.
    we are runnig the out loop in parallel not the inner loop. so for each i and j loop will run in sequential case1 = (i =1 and j =0 to n), case2 = (i = k and j =0 to n)
    if we run case1 1st then case2 or in the same time it wont make a difference .

    I think your algorithm is too naive
    Yeah, I know.

    I think it is possible to come up with an algorithm that makes use of already calculated results to cut off calculations for further input
    if i removed the matched result from vectorB, will that improve the speed ?? such as : :VectorB.remove(j)" each time i found a match. idk what slow down from removing element from random location in a vector

  13. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    Quote Originally Posted by jesse_mark View Post
    we are runnig the out loop in parallel not the inner loop. so for each i and j loop will run in sequential case1 = (i =1 and j =0 to n), case2 = (i = k and j =0 to n)
    I know that but the thing is multiple threads are concurrently accessing the same data which may lead to race conditions or data corruption. I don't know how the OpenMP compiler will react to it. Based on your problems with incrementing the counter, it doesn't exactly work correctly.

    if i removed the matched result from vectorB, will that improve the speed ?? such as : :VectorB.remove(j)" each time i found a match.
    No, that would lead to a race condition among threads and it would also simply be incorrect. One point in B can be the closest point of more than one point in A.

    I was rather thinking about some heuristics that if B1 is closest to A1 and there is some relation between A1 and A2 then Bx will not be closer to A2 than B1. I think Dijkstra's algorithm could be adapted for this case.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #13
    Join Date
    Jun 2012
    Posts
    173
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    48
    Thanked 2 Times in 2 Posts

    Default Re: update progressBar in parallel loop, using OpenMP

    No, that would lead to a race condition among threads and it would also simply be incorrect. One point in B can be the closest point of more than one point in A.
    if we consider the sequential case of using one thread. Also in my case each point in B is close to only one point in A. ?? does the remove could do any improve??

    Actaully i have tried it. and i had improve in one case and other case it slow it down.

    case1 was vectorA >> vectorB .... time improve.

    case2 was vectorB >> vectorA .... slow down.

    thank you so much, your suggestions are highly appreciated.

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: update progressBar in parallel loop, using OpenMP

    Quote Originally Posted by jesse_mark View Post
    does the remove could do any improve??
    Only if you use just one thread.

    Try keeping both vectors sorted by the X position (sort while inserting, not after all data is there)

    Then start iterating over the B vector. If the point you are checking fulfills condition (Xb-Xa) >= dist where "dist" is the distance between point in vector A which you are trying to find the closest point to and point in B that has the minimum distance found so far then you can stop checking all further points because they will be further away from point in A than the currently found point. If you start searching from the middle of vector B, you can do the same in the other direction. In many cases this will shorten the lookup significantly. If you connect that with removing already taken points from the B vector, you should get additional speedup for single-threaded approach.


    Added after 27 minutes:


    Here is a potential Qt5 implementation (I don't know if it works correctly, I haven't checked the results):

    Qt Code:
    1. #include <QCoreApplication> // QT += core
    2. #include <QtConcurrent> // QT += concurrent
    3.  
    4. bool lessThanX(const QPoint &pt1, const QPoint &pt2) {
    5. return pt1.x() < pt2.x();
    6. }
    7.  
    8. static QAtomicInt ignored = 0;
    9.  
    10. struct FindClosestPoint
    11. {
    12. FindClosestPoint(const QVector<QPoint> &vec) : B(vec) {}
    13.  
    14.  
    15. typedef QPoint result_type;
    16.  
    17. QPoint operator()(const QPoint &point)
    18. {
    19. QPoint candidate;
    20. double distance = -1;
    21. const int len = B.size();
    22. candidate = B.at(0);
    23. distance = (point-B.at(0)).manhattanLength(); // for simplicity, you can use Euclidean distance
    24. for(int i=1;i < len; ++i) {
    25. if(qAbs(point.x()-B.at(i).x()) >= distance){
    26. qDebug() << "Ignored" << len-i-1 << "elements";
    27. ignored.fetchAndAddAcquire(len-i-1);
    28. return candidate; // stop condition
    29. }
    30. double newDist = (point-B.at(i)).manhattanLength(); // for simplicity
    31. if(newDist < distance) {
    32. distance = newDist;
    33. candidate = B.at(i);
    34. }
    35. }
    36. return candidate;
    37. }
    38.  
    39. QVector<QPoint> B;
    40. };
    41.  
    42. int main(int argc, char *argv[])
    43. {
    44. QVector<QPoint> A;
    45. QVector<QPoint> B;
    46.  
    47. qsrand(QDateTime::currentDateTime().toTime_t());
    48.  
    49. int lenA = qrand() % 1000;
    50. int lenB = qrand() % 1000;
    51.  
    52. for(int i=0;i<lenA;++i) {
    53. QPoint pt(qrand() % 100, qrand() % 100);
    54. QVector<QPoint>::iterator iter = qLowerBound(A.begin(), A.end(), pt, lessThanX);
    55. A.insert(iter, pt);
    56. }
    57.  
    58. for(int i=0; i<lenB; ++i) {
    59. QPoint pt(qrand() % 100, qrand() % 100);
    60. QVector<QPoint>::iterator iter = qLowerBound(B.begin(), B.end(), pt, lessThanX);
    61. B.insert(iter, pt);
    62. }
    63.  
    64. QVector<QPoint> results = QtConcurrent::blockingMapped(A, FindClosestPoint(B));
    65.  
    66. for(int i=0;i<results.count();++i) {
    67. qDebug() << i << A.at(i) << results.at(i);
    68. }
    69. int totIgnored = ignored.load();
    70. qDebug() << "Average ignored elements:" << totIgnored << "out of " << A.size()*B.size();
    71. return 0;
    72. }
    To copy to clipboard, switch view to plain text mode 

    Of course every run is different but my tests show a 40-60% reduction in execution time (using 6 core CPU) compared to an unsorted approach (e.g. 10ms vs 33ms). To calculate real speedup, you need to also consider the time needed to presort those vectors so the real speedup is somewhat smaller. Of course provided my algorithm is correctly implemented. Furthermore if you use the two-way approach, the speedup will be even nicer.
    Last edited by wysota; 23rd January 2013 at 22:16.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. The following user says thank you to wysota for this useful post:

    jesse_mark (24th January 2013)

Similar Threads

  1. Redirect printf and update progressbar
    By rouge in forum Newbie
    Replies: 2
    Last Post: 7th October 2011, 23:06
  2. OpenMP problems with Qt Creator
    By Coocos in forum Qt Tools
    Replies: 1
    Last Post: 29th November 2010, 14:12
  3. Qt + OpenMP missing pthreadGC2.dll
    By Sanuden in forum Installation and Deployment
    Replies: 1
    Last Post: 30th March 2010, 14:13
  4. Progress Bar set value inside OpenMP parallel for
    By lixo1 in forum Qt Programming
    Replies: 2
    Last Post: 18th February 2010, 19:51
  5. QThread and OpenMP on Mac problem
    By Debilski in forum Qt Programming
    Replies: 0
    Last Post: 7th April 2009, 17:41

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.