Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <omp.h>
- // using omp_get_max_threads
- #include <cmath>
- // using std::fabsf, HUGE_VALF
- #include <chrono>
- // using std::chrono::*
- #include <random>
- // using std::default_random_engine, std::seedq, std::uniform_*_distribution
- #include <iostream>
- // using std::cout
- #include <boost/thread/mutex.hpp>
- // using boost::mutex
- #include <boost/thread/shared_mutex.hpp>
- // using boost::shared_mutex
- #include <boost/thread/lock_guard.hpp>
- // using boost::lock_guard
- #include <boost/thread/shared_lock_guard.hpp>
- // using boost::shared_lock_guard
- namespace {
- #ifdef USE_RWLOCK
- using mutex_type = boost::shared_mutex;
- using read_lock_type = boost::shared_lock_guard<mutex_type>;
- #else
- using mutex_type = boost::mutex;
- using read_lock_type = boost::lock_guard<mutex_type>;
- #endif
- using write_lock_type = boost::lock_guard<mutex_type>;
- enum class Direction { up, down, left, right };
- struct Vector2f
- {
- float x, y;
- constexpr Vector2f(float x=0.f, float y=0.f) noexcept
- : x(x), y(y)
- {}
- };
- struct UnitState
- {
- Vector2f position, velocity;
- Direction facing;
- constexpr UnitState() noexcept
- : position(), velocity(), facing(Direction::up)
- {}
- };
- class GameUnit
- {
- mutable mutex_type mutex;
- UnitState state;
- float maxSpeed;
- public:
- GameUnit() noexcept
- : mutex(), state(), maxSpeed(HUGE_VALF)
- {}
- UnitState getFullState() const
- {
- read_lock_type lock(mutex);
- return state;
- }
- void updatePosition(float x, float y, Direction facing)
- {
- write_lock_type lock(mutex);
- if(std::fabs(state.position.x - x) > maxSpeed
- || std::fabs(state.position.y - y) > maxSpeed)
- return;
- state.position.x = x;
- state.position.y = y;
- state.facing = facing;
- }
- };
- }
- int main()
- {
- using clock_t = std::chrono::steady_clock;
- constexpr int maxReadsToWrites = 1000;
- constexpr std::chrono::seconds seconds(10);
- const clock_t::duration clock_seconds =
- std::chrono::duration_cast<clock_t::duration>(seconds);
- const int maxThreads = omp_get_max_threads();
- std::seed_seq seed;
- std::uniform_real_distribution<float> floatDistr;
- for(int readsToWrites = 1; readsToWrites <= maxReadsToWrites; readsToWrites *= 10) {
- std::uniform_int_distribution<int> intDistr(0, readsToWrites);
- for(int threads = 1; threads <= maxThreads; threads *= 2) {
- GameUnit unit;
- double opsPerSec = 0.;
- const clock_t::time_point startTime = clock_t::now();
- # pragma omp parallel num_threads(threads)
- {
- std::default_random_engine rnd;
- # pragma omp critical
- rnd = std::default_random_engine(seed);
- long long localOps = 0;
- clock_t::duration dt;
- Vector2f pos;
- for(localOps = 0; (dt = clock_t::now() - startTime) < clock_seconds;
- ++localOps) {
- if(intDistr(rnd))
- pos = unit.getFullState().position;
- else {
- pos.x += floatDistr(rnd);
- pos.y += floatDistr(rnd);
- unit.updatePosition(pos.x, pos.y, Direction::up);
- }
- }
- const double localOpsPerSec = localOps /
- (std::chrono::duration_cast<std::chrono::nanoseconds>(dt).count()
- * 1e-9);
- # pragma omp critical
- opsPerSec += localOpsPerSec;
- }
- std::cout << readsToWrites << " reads per write "
- << threads << " threads "
- << opsPerSec << " operations per second\n";
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement