Commit 462974b0 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

evolution

parent 71536324
This diff is collapsed.
......@@ -104,6 +104,8 @@ template<typename T, size_t len=vbytes/sizeof(T)> class vtp
template<typename I> void Set (I i, T val) { v[i]=val; }
template<typename I> T operator[](I i) const { return v[i]; }
};
template<typename T, size_t len> vtp<T, len> operator*(T a, vtp<T, len> b)
{ return b*a; }
}
using detail_simd::vtp;
......
......@@ -17,11 +17,12 @@
*/
/* Copyright (C) 2019 Peter Bell, Max-Planck-Society
Author: Peter Bell, Martin Reinecke */
Authors: Peter Bell, Martin Reinecke */
#ifndef MRUTIL_THREADING_H
#define MRUTIL_THREADING_H
#ifndef MRUTIL_NO_THREADING
#include <cstdlib>
#include <mutex>
#include <condition_variable>
......@@ -33,8 +34,7 @@
#if __has_include(<pthread.h>)
#include <pthread.h>
#endif
// FIXME: allow disabling multithreading altogether
#endif
namespace mr {
......@@ -42,9 +42,10 @@ namespace detail_threading {
using namespace std;
#ifndef MRUTIL_NO_THREADING
thread_local size_t thread_id = 0;
thread_local size_t num_threads = 1;
static const size_t max_threads = max(1u, thread::hardware_concurrency());
thread_local size_t num_threads_ = 1;
static const size_t max_threads_ = max(1u, thread::hardware_concurrency());
class latch
{
......@@ -149,7 +150,7 @@ class thread_pool
threads_(nthreads)
{ create_threads(); }
thread_pool(): thread_pool(max_threads) {}
thread_pool(): thread_pool(max_threads_) {}
~thread_pool() { shutdown(); }
......@@ -196,7 +197,7 @@ template <typename Func>
void thread_map(size_t nthreads, Func f)
{
if (nthreads == 0)
nthreads = max_threads;
nthreads = max_threads_;
if (nthreads == 1)
{ f(); return; }
......@@ -210,7 +211,7 @@ void thread_map(size_t nthreads, Func f)
pool.submit(
[&f, &counter, &ex, &ex_mut, i, nthreads] {
thread_id = i;
num_threads = nthreads;
num_threads_ = nthreads;
try { f(); }
catch (...)
{
......@@ -261,7 +262,7 @@ class Scheduler
size_t nthreads, size_t chunksize, Func f)
{
mode = STATIC;
nthreads_ = (nthreads==0) ? max_threads : nthreads;
nthreads_ = (nthreads==0) ? max_threads_ : nthreads;
nwork_ = nwork;
chunksize_ = (chunksize<1) ? (nwork_+nthreads_-1)/nthreads_
: chunksize;
......@@ -275,7 +276,7 @@ class Scheduler
size_t nthreads, size_t chunksize_min, double fact_max, Func f)
{
mode = DYNAMIC;
nthreads_ = (nthreads==0) ? max_threads : nthreads;
nthreads_ = (nthreads==0) ? max_threads_ : nthreads;
nwork_ = nwork;
chunksize_ = (chunksize_min<1) ? 1 : chunksize_min;
if (chunksize_*nthreads_>=nwork_)
......@@ -319,6 +320,58 @@ class Scheduler
}
};
template<typename Func> void execParallel(size_t nthreads, Func f)
{
nthreads = (nthreads==0) ? max_threads_ : nthreads;
thread_map(nthreads, move(f));
}
#else
constexpr size_t thread_id = 0;
constexpr size_t num_threads_ = 1;
constexpr size_t max_threads_ = 1;
class Scheduler
{
private:
size_t nwork_;
struct Range
{
size_t lo, hi;
Range() : lo(0), hi(0) {}
Range(size_t lo_, size_t hi_) : lo(lo_), hi(hi_) {}
operator bool() const { return hi>lo; }
};
public:
size_t nthreads() const { return 1; }
// mutex &mut() { return mut_; }
template<typename Func> void execSingle(size_t nwork, Func f)
{
nwork_ = nwork;
f(*this);
}
template<typename Func> void execStatic(size_t nwork,
size_t /*nthreads*/, size_t /*chunksize*/, Func f)
{ execSingle(nwork, move(f)); }
template<typename Func> void execDynamic(size_t nwork,
size_t /*nthreads*/, size_t /*chunksize_min*/, double /*fact_max*/,
Func f)
{ execSingle(nwork, move(f)); }
Range getNext()
{
return Range(0, nwork_);
nwork_=0;
}
};
template<typename Func> void execParallel(size_t /*nthreads*/, Func f)
{ f(); }
#endif
template<typename Func> void execSingle(size_t nwork, Func f)
{
Scheduler sched;
......@@ -342,6 +395,13 @@ template<typename Func> void execGuided(size_t nwork,
Scheduler sched;
sched.execDynamic(nwork, nthreads, chunksize_min, fact_max, move(f));
}
size_t num_threads()
{ return num_threads_; }
size_t thread_num()
{ return thread_id; }
size_t max_threads()
{ return max_threads_; }
} // end of namespace detail
using detail_threading::Scheduler;
......@@ -349,8 +409,10 @@ using detail_threading::execSingle;
using detail_threading::execStatic;
using detail_threading::execDynamic;
using detail_threading::execGuided;
// FIXME: missing execParallel(), my_thread(), num_threads()
using detail_threading::num_threads;
using detail_threading::thread_num;
using detail_threading::max_threads;
using detail_threading::execParallel;
} // end of namespace mr
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment