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:
Fischlurch 2024-11-16 13:30:22 +01:00
parent a15006d11a
commit a0336685dc
2 changed files with 67 additions and 13 deletions

View file

@ -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)
}
};

View file

@ -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 &quot;zuf&#xe4;llig&quot; kaputte Zahl au&#xdf;erhalb des Definitionsbereichs..."/>
<node CREATED="1731728442361" ID="ID_444376696" MODIFIED="1731753110424" TEXT="schlimmstenfalls eine &quot;zuf&#xe4;llig&quot; kaputte Zahl...">
<node CREATED="1731753113229" ID="ID_792260744" MODIFIED="1731753304842" TEXT="diese k&#xf6;nnte theoretisch au&#xdf;erhalb des Definitionsbereichs liegen"/>
<node CREATED="1731753438455" ID="ID_518457223" MODIFIED="1731753543440" TEXT="tats&#xe4;chlich auf meiner Maschine ist das unm&#xf6;glich (ulong &#x2261; uint64_t)"/>
<node CREATED="1731753607692" ID="ID_759994737" MODIFIED="1731753666983" TEXT="man k&#xf6;nnte das aber mit der &#xbb;kleinen&#xab; 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&#xfc;fen"/>
<node CREATED="1731728641175" ID="ID_177314578" MODIFIED="1731728668212" TEXT="MIttelwert pr&#xfc;fen (bias)"/>
<node CREATED="1731728672328" ID="ID_132879815" MODIFIED="1731728703703" TEXT="1. Test : 1 Million Aufrufe &#x27f9; sieht gut aus"/>
<node COLOR="#338800" CREATED="1731728672328" ID="ID_132879815" MODIFIED="1731753690121" TEXT="1. Test : 1 Million Aufrufe &#x27f9; 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&#xdf;er z&#xe4;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&#xe4;ufe &#x27f9; &#x201e;interesting&#x201c;">
<icon BUILTIN="broken-line"/>
<node COLOR="#435e98" CREATED="1731758648783" ID="ID_1184185994" MODIFIED="1731759736183" TEXT="die 64-bit Engine zeigt keine Auff&#xe4;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&#xe4;ufig Defekte">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1731758777055" ID="ID_1355078435" MODIFIED="1731758789311" TEXT="in ~80% der L&#xe4;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&#xfc;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>