Hello everybody At FOSDEM we did some work to use the OpenMP framework. I have continued working on it since and these are my conclusions
EXECUTIVE SUMMARY OpenMP integration is really stellar. Basically building an non-openmp wesnoth with openmp code is trivial, integration with build systems should be very easy and there is no cost if openmp is compiled out. I can't measure the cost of having openmp enabled on a single-core processor but I expect it to be very low Modifying wesnoth code to be OpenMP aware is not trivial but is probably still the easiest way to gain performance from multi-core CPUs. It requires some thourough testing (like any SMP code) but overall I had little trouble finding the offending code. Problems ususally didn't happen on the offending code but on related variables. Overall I think OpenMP is the way to go, but only on areas where process paralelization makes sense (AI and WML parsing comes to mind) TEST CASE AND PERFORMANCE GAIN I tested OpenMP on the unit invalidation code. Basically the animation engine calculates between each redraw what units are invalidated, what hex they overlap, mark those hex they overlap and repeat this until all units that need to be invalidated are invalidated This area of code is calculation-intensive but is logically read-only (except when mergin the results of the calculations). It is also one of the most CPU intensive areas of the animation engine, so it was a good target for OMP. A non-scientific measure showed a reduction of the average AI turn on a AI vs AI game of 8% on my 4core HT computer. So this is not neglectable. INTEGRATING OPENMP Except for a few diagnostic calls (in an omp.h include file) OpenMP is entirely pragma based. In theory compilers should ignore unknown pragmas so OMP code can be compiled with no change when OMP is disabled As a cautionary measure I have surrounded all OMP pragmas with #ifdef _OPENMP... Mainly because we compile with -Werror and I would be suprise if there isn't at least one compiler that produces warnings on unknown pragmas. this particular flag (_OPENMP) is set by the compiler when OMP is enabled, so there is no need to set it manually. Thus, when compiling with GCC, enabling OMP is just a matter of adding the -fopenmp flag and linking with -lgomp (which can also be used to detect if openmp is available on the computer) GENERAL OPENMP CODING PHILOSOPHY OpenMP is built to allow easy integration in single thread applications. I maintains a pool of threads ready, and whenever an OpenMP pragma is encountered it will run all threads on the corresponding code. Typically, a simple for loop will see its iterations shared between threads that will run their code in parallel and rejoin at the end of the loop. A few extra constructs allow to declare which variables are shared or copied between thread, and if an area within the loop must be run in order/run by only one thread. Overall I recommend reading http://bisqwit.iki.fi/story/howto/openmp/ which is a rather good tutorial. Once a suitable area for OpenMP is identified, the tricky part is to understand clearly what happens in the code that we are handling. The reason it took me so long to integrate OpenMP was that I hadn't realized that reading an image meant writing it in the cache, and thus the image cache had to be protected. Once that was figured out, adding criticall section around the variable access was easy. Same thing with SDL surfaces that need to be protected because they are ref-counted. TRICKS AND ADVICES * read the documentation, don't start coding right away. There are some fine details that need to be understood * test a lot. Some crashes are pretty rare. Though once they happen they are relatively easy to track down * always set the default(none) on the for pragma * don't hunt every loop in the code, only add OMP where it makes sense * remember that STL is not threadsafe. Reading is alright, but protect any STL variable that is written within openMP Happy hacking... _______________________________________________ Wesnoth-dev mailing list Wesnoth-dev@gna.org https://mail.gna.org/listinfo/wesnoth-dev