Library: investigate glitches when drawing concurrently
Further investigation shows that the ''data type used for computation'' plays a crucial role. The (recommended) 64bit mersenne twister uses the full value range of the working data type, which on a typical 64bit system is also `uint64_t`. In this case, values corrupted by concurrency go unnoticed. This can be **verified empirically** : the distribution of shifts from the theoretical mean value is in the expected low range < 2‰ However, when using the 32bit mersenne engine, the working data type is still uint64_t. In this case a **significant number of glitches** can be shown empricially. When drawing 1 Million values, in 80% of all runs at least one glitch and up to 5 glitches can happen, and the mean values are **significantly skewed**
This commit is contained in:
parent
a15006d11a
commit
a0336685dc
2 changed files with 67 additions and 13 deletions
|
|
@ -37,15 +37,20 @@
|
|||
#include "lib/test/diagnostic-output.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <tuple>
|
||||
//#include <array>
|
||||
//using util::isLimited;
|
||||
//using std::array;
|
||||
using std::tuple;
|
||||
using std::deque;
|
||||
|
||||
namespace lib {
|
||||
namespace test {
|
||||
|
||||
namespace {
|
||||
const uint NUM_THREADS = 8;
|
||||
|
||||
const uint NUM_INVOKE = 1'000'000;
|
||||
const uint NUM_REPEATS = 10;
|
||||
const uint NUM_INVOKES = 1'000'000;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -71,36 +76,47 @@ namespace test {
|
|||
investigate_concurrentAccess()
|
||||
{
|
||||
struct Results
|
||||
: std::deque<double>
|
||||
: deque<tuple<double,uint>>
|
||||
, Sync<>
|
||||
{
|
||||
void
|
||||
post (double val)
|
||||
post (double err, uint fails)
|
||||
{
|
||||
Lock sync(this);
|
||||
push_back (val);
|
||||
emplace_back (err, fails);
|
||||
}
|
||||
};
|
||||
|
||||
Results results;
|
||||
|
||||
const uint N = NUM_INVOKE;
|
||||
auto expect = RAND_MAX / 2;
|
||||
using Engine = std::mt19937;
|
||||
// using Engine = std::mt19937_64;
|
||||
|
||||
Engine ranGen{defaultGen.u64()};
|
||||
|
||||
const uint N = NUM_INVOKES;
|
||||
auto expect = (Engine::max() - Engine::min()) / 2;
|
||||
|
||||
auto drawRandom = [&]()
|
||||
{
|
||||
uint fail{0};
|
||||
double avg{0.0};
|
||||
for (uint i=0; i<N; ++i)
|
||||
avg += 1.0/N * rani();
|
||||
{
|
||||
auto r = ranGen();
|
||||
if (r < Engine::min() or r > Engine::max())
|
||||
++fail;
|
||||
avg += 1.0/N * (r % Engine::max());
|
||||
}
|
||||
auto error = avg/expect - 1;
|
||||
results.post (error);
|
||||
results.post (error, fail);
|
||||
};
|
||||
|
||||
auto [dur,sum] = threadBenchmark<NUM_THREADS> (drawRandom, 1);
|
||||
auto [dur,sum] = threadBenchmark<NUM_THREADS> (drawRandom, NUM_REPEATS);
|
||||
for (auto res : results)
|
||||
SHOW_EXPR(res);
|
||||
SHOW_EXPR(sum)
|
||||
SHOW_EXPR(dur/NUM_INVOKE)
|
||||
SHOW_EXPR(dur/NUM_INVOKES)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -58053,14 +58053,52 @@
|
|||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1731728402020" ID="ID_216802866" MODIFIED="1731728433241" TEXT="theoretisch ist PRNG nicht thread-safe"/>
|
||||
<node CREATED="1731728433837" ID="ID_975708385" MODIFIED="1731728441330" TEXT="aber ... was kann schon passieren??"/>
|
||||
<node CREATED="1731728442361" ID="ID_444376696" MODIFIED="1731728582512" TEXT="schlimmstenfalls eine "zufällig" kaputte Zahl außerhalb des Definitionsbereichs..."/>
|
||||
<node CREATED="1731728442361" ID="ID_444376696" MODIFIED="1731753110424" TEXT="schlimmstenfalls eine "zufällig" kaputte Zahl...">
|
||||
<node CREATED="1731753113229" ID="ID_792260744" MODIFIED="1731753304842" TEXT="diese könnte theoretisch außerhalb des Definitionsbereichs liegen"/>
|
||||
<node CREATED="1731753438455" ID="ID_518457223" MODIFIED="1731753543440" TEXT="tatsächlich auf meiner Maschine ist das unmöglich (ulong ≡ uint64_t)"/>
|
||||
<node CREATED="1731753607692" ID="ID_759994737" MODIFIED="1731753666983" TEXT="man könnte das aber mit der »kleinen« mersenne-Engine mt19937 untersuchen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
diese verwendet uint_fast32_t, das aber auf meinem System ebenfalls auf unit64_t gemapped ist
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1731728584572" ID="ID_1568853077" MODIFIED="1731728594906" TEXT="empirisch untersuchen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1731728599474" ID="ID_1952720762" MODIFIED="1731728615563" TEXT="mit allen Cores parallel Zufallszahlen ziehen"/>
|
||||
<node CREATED="1731728616535" ID="ID_59784960" MODIFIED="1731728640632" TEXT="einzelne Zahlen prüfen"/>
|
||||
<node CREATED="1731728641175" ID="ID_177314578" MODIFIED="1731728668212" TEXT="MIttelwert prüfen (bias)"/>
|
||||
<node CREATED="1731728672328" ID="ID_132879815" MODIFIED="1731728703703" TEXT="1. Test : 1 Million Aufrufe ⟹ sieht gut aus"/>
|
||||
<node COLOR="#338800" CREATED="1731728672328" ID="ID_132879815" MODIFIED="1731753690121" TEXT="1. Test : 1 Million Aufrufe ⟹ sieht gut aus">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731753678938" ID="ID_950235371" MODIFIED="1731753692113" TEXT="sollte direkt mit dem Generator testen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731758573419" ID="ID_418477657" MODIFIED="1731758588364" TEXT="Generator-Varianten und Ausreißer zählen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731758589307" ID="ID_423237560" MODIFIED="1731759752156" TEXT="2. Test : 1 Mio, jeweils 10 Läufe ⟹ „interesting“">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node COLOR="#435e98" CREATED="1731758648783" ID="ID_1184185994" MODIFIED="1731759736183" TEXT="die 64-bit Engine zeigt keine Auffälligkeiten">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731758663138" ID="ID_1922697990" MODIFIED="1731759739989" TEXT="mit der 32-bit Engine gibt es häufig Defekte">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1731758777055" ID="ID_1355078435" MODIFIED="1731758789311" TEXT="in ~80% der Läufe ist ein Defekt aufgetreten"/>
|
||||
<node CREATED="1731758789923" ID="ID_1444531910" MODIFIED="1731758802573" TEXT="maximal bis 5 Defekte / 1Mio Aufrufe"/>
|
||||
<node CREATED="1731758825988" ID="ID_340204788" MODIFIED="1731758907442" TEXT="es ist dann (natürlich) auch der Mittelwert deutlich verschoben"/>
|
||||
<node CREATED="1731758877602" ID="ID_612988576" MODIFIED="1731758895038" TEXT="und insgesamt ist ein deutlicher Bias (zu positiven Werten) feststellbar"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue