Team-Doominati / Doominati

Avoiding the sins of ZDoom since 2016.
GNU General Public License v2.0
7 stars 1 forks source link

Threading #16

Closed marrub-- closed 7 years ago

marrub-- commented 8 years ago

We have manual threading, C++11 threading, and script threading.

I'm thinking, though, that OpenMP may be useful as well for certain big operations which have no mutual exclusion needs.

OpenMP is fairly unintrusive, providing compiler pragmas when supported.

For example:

// openmptest.cpp

#include <cmath>
#include <chrono>
#include <iostream>

int main()
{
   constexpr double tau = 3.14159265359 * 2.0;
   constexpr std::size_t tableLen = 900'000;

   static double sineTable[tableLen], cosineTable[tableLen];

   auto begin = std::chrono::high_resolution_clock::now();

#ifdef USEOPENMP
   #pragma omp parallel for
#endif
   for(std::size_t i = 0; i < tableLen; i++)
   {
      sineTable[i]   = std::sin(tau * (i / double(tableLen)));
      cosineTable[i] = std::cos(tau * (i / double(tableLen)));
   }

   auto end = std::chrono::high_resolution_clock::now();

   for(std::size_t i = 0; i < tableLen; i++)
      if((i % 10000) == 9999)
         std::cout << sineTable[i] << '\t' << cosineTable[i] << '\n';

   auto durationNS =
      std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin);
   auto durationMS =
      std::chrono::duration_cast<std::chrono::microseconds>(end - begin);

   std::cout << "done in " << durationNS.count() <<   "ns ("
                           << durationMS.count() << u8"µs)\n";
}

// EOF

Compile with clang++ openmptest.cpp -std=c++1z -o b.out and you get:

...
-0.275644       0.96126
-0.207919       0.978146
-0.13918        0.990267
-0.0697634      0.997564
-6.98132e-06    1
done in 151062290ns (151062µs)

But, compile with clang++ openmptest.cpp -std=c++1z -DUSEOPENMP -fopenmp -o a.out and,

...
-0.275644       0.96126
-0.207919       0.978146
-0.13918        0.990267
-0.0697634      0.997564
-6.98132e-06    1
done in 50347741ns (50347µs)

A very noticable increase in speed, essentially for free, just by adding a compiler pragma.

Thoughts?

Kyle873 commented 8 years ago

This will be extremely useful, as one of the things I ran into trying to implement on different engines was intensive map procedural generation halting the main thread while it ran. The proper behavior would be to do this kind of intensive work in a thread(s) so that things such as a loading screen and progress could be displayed.

marrub-- commented 7 years ago

Closing this because OpenMP is now part of the CMakeLists. Any time threading can be easily applied it should be, but it's obviously not something one should go out of their way for.