Top 15 Mistakes in OpenMP
It has been a while since I have done this little experiment, but I still find the results interesting. As some of you may know, I teach a class on parallel programming (this is an undergraduate class, by the way – may I have a million dollar in funding now as well, please? 😎 ). The first parallel programming system we teach to our students is OpenMP. There is no written test at the end of the class, but instead the students get to do assignments in teams of two people, which have to be defended before us. This is really educational for us (and I think for the students as well), because we get to see and find the mistakes our students make. I have done a little statistic on what mistakes are made by our students, and in this post you will find the results. Why am I posting a list of mistakes? Because I think learning from other peoples mistakes is almost as good as learning from my own, and usually saves quite a lot of time compared to the first option. 😀
I have chosen to divide the mistakes into two groups: correctness mistakes and performance mistakes. Correctness mistakes impact the correctness of the program (I can’t believe I am explaining this – I must be on a writing spree 🙄 ), leading to wrong results when made. Performance mistakes merely lead to slower programs. And now I have kept you waiting long enough, here is my list of the top mistakes to make when programming in OpenMP:
Correctness Mistakes
- Access to shared variables not protected
- Use of locks without flush (as of OpenMP 2.5, this is no longer a mistake)
- Read of shared variable without obeying the memory model
- Forget to mark private variables as such
- Use of ordered clause without ordered construct
- Declare loop variable in for-construct as shared
- Forget to put down for in #pragma omp parallel for
- Try to change the number of threads in a parallel region, after it has been started already
- omp_unset_lock() called from non-owner thread
- Attempt to change loop variable while in #pragma omp for
Performance Mistakes
- Use of critical when atomic would be sufficient
- Put too much work inside critical region
- Use of orphaned construct outside parallel region
- Use of unnecessary flush
- Use of unnecessary critical
Disclaimer
Famous last words
With this out of the way, let me tell you that I have written a paper about the experiment and some best practices to avoid them in the first place (which I may post here later). If you don’t understand some of the mistakes posted above, please look up the verbose explanations there. There is blog by Yuan Lin dedicated to the sole purpose of showing common mistakes while programming in parallel – called Touch Dreams. Unfortunately, it appears to be no longer maintained. What a pity, I think we could use more resources on mistakes and how to avoid them…