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

Reply via email to