From 4a150132e1a1c801ffa6e18264abe8d680c9c0bc Mon Sep 17 00:00:00 2001 From: Person Date: Wed, 24 Jul 2019 18:29:33 -0700 Subject: [PATCH] --User changes -Improve performance in the following variations: cpow2, dc_cube, julia3d, julia3dz, julian2, log_db, nblur, npolar, waffle, wavesn, xtrb. --Code changes -Rand range now uses multiply + shift rather than modulo. --- Source/Ember/Ember.h | 6 +- Source/Ember/Isaac.h | 26 ++++----- Source/Ember/PaletteList.cpp | 4 +- Source/Ember/SheepTools.h | 24 ++++---- Source/Ember/Variations03.h | 9 ++- Source/Ember/Variations06.h | 2 +- Source/EmberCL/EmberCLFunctions.h | 2 +- Source/EmberGenome/EmberGenome.cpp | 8 +-- Source/EmberTester/EmberTester.cpp | 93 +++++++++++++++++++++--------- 9 files changed, 108 insertions(+), 66 deletions(-) diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h index 013cec0..215a57b 100644 --- a/Source/Ember/Ember.h +++ b/Source/Ember/Ember.h @@ -1078,11 +1078,11 @@ public: }; if (rand.Rand() & 1) - sym = symDistrib[rand.Rand() % Vlen(symDistrib)]; + sym = symDistrib[rand.Rand(Vlen(symDistrib))]; else if (rand.Rand() & 31) - sym = intmax_t(rand.Rand() % 13) - 6; + sym = intmax_t(rand.Rand(13)) - 6; else - sym = intmax_t(rand.Rand() % 51) - 25; + sym = intmax_t(rand.Rand(51)) - 25; } if (sym == 1 || sym == 0) diff --git a/Source/Ember/Isaac.h b/Source/Ember/Isaac.h index 58e0298..9c0b13e 100644 --- a/Source/Ember/Isaac.h +++ b/Source/Ember/Isaac.h @@ -148,9 +148,9 @@ public: /// /// A value one greater than the maximum value that will be returned /// A value between 0 and the value passed in minus 1 - inline T Rand(T upper) + inline T Rand(size_t upper) { - return (upper == 0) ? Rand() : Rand() % upper; + return (upper == 0) ? Rand() : T(((size_t)Rand() * upper) >> 32); } /// @@ -158,7 +158,7 @@ public: /// /// A value one greater than the maximum value that will be returned /// A value between 0 and the value passed in minus 1 - static inline T LockedRand(T upper) + static inline T LockedRand(size_t upper) { rlg l(*s_CS.get()); T t = GlobalRand->Rand(upper); @@ -420,14 +420,14 @@ protected: { #ifndef __ISAAC64 RngStep((a << 13), a, b, mm, m, m2, r, x, y); - RngStep((a >> 6) , a, b, mm, m, m2, r, x, y); - RngStep((a << 2) , a, b, mm, m, m2, r, x, y); + RngStep((a >> 6), a, b, mm, m, m2, r, x, y); + RngStep((a << 2), a, b, mm, m, m2, r, x, y); RngStep((a >> 16), a, b, mm, m, m2, r, x, y); #else // __ISAAC64 RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y); - RngStep( a ^ (a >> 5) , a, b, mm, m, m2, r, x, y); - RngStep( a ^ (a << 12) , a, b, mm, m, m2, r, x, y); - RngStep( a ^ (a >> 33) , a, b, mm, m, m2, r, x, y); + RngStep( a ^ (a >> 5), a, b, mm, m, m2, r, x, y); + RngStep( a ^ (a << 12), a, b, mm, m, m2, r, x, y); + RngStep( a ^ (a >> 33), a, b, mm, m, m2, r, x, y); #endif // __ISAAC64 } @@ -437,14 +437,14 @@ protected: { #ifndef __ISAAC64 RngStep((a << 13), a, b, mm, m, m2, r, x, y); - RngStep((a >> 6) , a, b, mm, m, m2, r, x, y); - RngStep((a << 2) , a, b, mm, m, m2, r, x, y); + RngStep((a >> 6), a, b, mm, m, m2, r, x, y); + RngStep((a << 2), a, b, mm, m, m2, r, x, y); RngStep((a >> 16), a, b, mm, m, m2, r, x, y); #else // __ISAAC64 RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y); - RngStep( a ^ (a >> 5) , a, b, mm, m, m2, r, x, y); - RngStep( a ^ (a << 12) , a, b, mm, m, m2, r, x, y); - RngStep( a ^ (a >> 33) , a, b, mm, m, m2, r, x, y); + RngStep( a ^ (a >> 5), a, b, mm, m, m2, r, x, y); + RngStep( a ^ (a << 12), a, b, mm, m, m2, r, x, y); + RngStep( a ^ (a >> 33), a, b, mm, m, m2, r, x, y); #endif // __ISAAC64 } diff --git a/Source/Ember/PaletteList.cpp b/Source/Ember/PaletteList.cpp index a637ea2..08337b0 100644 --- a/Source/Ember/PaletteList.cpp +++ b/Source/Ember/PaletteList.cpp @@ -269,7 +269,7 @@ Palette* PaletteList::GetRandomPalette() while (attempts < Size() * 10) { auto p = s_Palettes.begin(); - auto paletteFileIndex = QTIsaac::LockedRand() % Size(); + auto paletteFileIndex = QTIsaac::LockedRand(Size()); size_t i = 0; //Move p forward i elements. @@ -281,7 +281,7 @@ Palette* PaletteList::GetRandomPalette() if (i < Size()) { - size_t paletteIndex = QTIsaac::LockedRand() % p->second.size(); + size_t paletteIndex = QTIsaac::LockedRand(p->second.size()); if (paletteIndex < p->second.size() && !p->second[paletteIndex].IsEmpty()) return &p->second[paletteIndex]; diff --git a/Source/Ember/SheepTools.h b/Source/Ember/SheepTools.h index 856631d..56872e4 100644 --- a/Source/Ember/SheepTools.h +++ b/Source/Ember/SheepTools.h @@ -254,7 +254,7 @@ public: //Generate a 2-xform random. Random(mutation, useVars, sym, 2, maxVars); //Which xform to mutate? - modXform = m_Rand.Rand() % ember.TotalXformCount(); + modXform = m_Rand.Rand(ember.TotalXformCount()); auto xform1 = ember.GetTotalXform(modXform); auto xform2 = mutation.GetTotalXform(0); os << "mutate xform " << modXform << " coefs"; @@ -280,7 +280,7 @@ public: else if (mode == eMutateMode::MUTATE_POST_XFORMS) { bool same = (m_Rand.Rand() & 3) > 0;//25% chance of using the same post for all of them. - size_t b = 1 + m_Rand.Rand() % 6; + size_t b = 1 + m_Rand.Rand(6); os << "mutate post xforms " << b << (same ? " same" : ""); for (size_t i = 0; i < ember.TotalXformCount(); i++) @@ -387,7 +387,7 @@ public: } else if (mode == eMutateMode::MUTATE_DELETE_XFORM) { - size_t nx = m_Rand.Rand() % ember.TotalXformCount(); + size_t nx = m_Rand.Rand(ember.TotalXformCount()); os << "mutate delete xform " << nx; if (ember.TotalXformCount() > 1) @@ -626,7 +626,7 @@ public: } else { - ember.AddXforms(xformDistrib[m_Rand.Rand() % Vlen(xformDistrib)]); + ember.AddXforms(xformDistrib[m_Rand.Rand(Vlen(xformDistrib))]); addfinal = m_Rand.Frand01() < T(0.15);//Add a final xform 15% of the time. if (addfinal) @@ -639,7 +639,7 @@ public: //If useVars is empty, randomly choose one to use or decide to use multiple. if (useVars.empty()) - var = m_Rand.RandBit() ? m_Rand.Rand() % varCount : -1; + var = m_Rand.RandBit() ? m_Rand.Rand(varCount) : -1; else var = -2; @@ -689,7 +689,7 @@ public: else if (multid && var == -1) { if (xform->TotalVariationCount() < maxVars) - xform->AddVariation(m_VariationList->GetVariation(m_Rand.Rand() % varCount)->Copy());//Choose a random var for this xform. + xform->AddVariation(m_VariationList->GetVariation(m_Rand.Rand(varCount))->Copy());//Choose a random var for this xform. } else { @@ -722,7 +722,7 @@ public: if (var != -2) { //Pick a random variation and use a random weight from 0-1. - Variation* v = m_VariationList->GetVariationCopy(static_cast(m_Rand.Rand() % varCount), m_Rand.Frand(T(0.001), 1)); + Variation* v = m_VariationList->GetVariationCopy(static_cast(m_Rand.Rand(varCount)), m_Rand.Frand(T(0.001), 1)); if (v && !xform->AddVariation(v)) delete v;//It already existed and therefore was not added. @@ -730,7 +730,7 @@ public: else { //Pick a random variation from the suppled IDs and use a random weight from 0-1. - Variation* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand(T(0.001), 1)); + Variation* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand(T(0.001), 1)); if (v && !xform->AddVariation(v)) delete v; @@ -760,12 +760,12 @@ public: if (var != -2) { //Pick a random variation and use a random weight from 0-1. - xform->AddVariation(m_VariationList->GetVariationCopy(static_cast(m_Rand.Rand() % varCount), m_Rand.Frand(T(0.001), 1))); + xform->AddVariation(m_VariationList->GetVariationCopy(static_cast(m_Rand.Rand(varCount)), m_Rand.Frand(T(0.001), 1))); } else { //Pick a random variation from the suppled IDs and use a random weight from 0-1. - xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand(T(0.001), 1))); + xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand(T(0.001), 1))); } } } @@ -779,7 +779,7 @@ public: } //Randomly add symmetry (but not if we've already added a final xform). - if (sym || (!(m_Rand.Rand() % 4) && !addfinal)) + if (sym || (!(m_Rand.Rand(4)) && !addfinal)) ember.AddSymmetry(sym, m_Rand); else ember.m_Symmetry = 0; @@ -932,7 +932,7 @@ public: while (ntries++ < 100) { - size_t i = m_Rand.Rand() % ember.TotalXformCount(); + size_t i = m_Rand.Rand(ember.TotalXformCount()); if (i != excluded) { diff --git a/Source/Ember/Variations03.h b/Source/Ember/Variations03.h index 780e8b0..3ed273b 100644 --- a/Source/Ember/Variations03.h +++ b/Source/Ember/Variations03.h @@ -1777,7 +1777,7 @@ public: T temp = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(uint(m_AbsN))) / m_N; helper.Out.x = r * std::cos(temp); helper.Out.y = r * std::sin(temp); - helper.Out.z = r * helper.In.z / (helper.m_PrecalcSqrtSumSquares * m_AbsN); + helper.Out.z = r * helper.In.z / Zeps(helper.m_PrecalcSqrtSumSquares * m_AbsN); } virtual string OpenCLString() const override @@ -1796,11 +1796,16 @@ public: << "\n" << "\t\tvOut.x = r * cos(temp);\n" << "\t\tvOut.y = r * sin(temp);\n" - << "\t\tvOut.z = r * vIn.z / (precalcSqrtSumSquares * " << absn << ");\n" + << "\t\tvOut.z = r * vIn.z / Zeps(precalcSqrtSumSquares * " << absn << ");\n" << "\t}\n"; return ss.str(); } + virtual vector OpenCLGlobalFuncNames() const override + { + return vector { "Zeps" }; + } + virtual void Precalc() override { m_AbsN = std::abs(m_N); diff --git a/Source/Ember/Variations06.h b/Source/Ember/Variations06.h index 04f1a77..793db23 100644 --- a/Source/Ember/Variations06.h +++ b/Source/Ember/Variations06.h @@ -859,7 +859,7 @@ private: if (params.ExactCalc == 1) angXY = rand.Frand01() * M_2PI; else - angXY = (std::atan(params.ArcTan1 * (rand.Frand01() - T(0.5))) / params.ArcTan2 + T(0.5) + T(rand.Rand() % glm::uint(params.NumEdges))) * params.MidAngle; + angXY = (std::atan(params.ArcTan1 * (rand.Frand01() - T(0.5))) / params.ArcTan2 + T(0.5) + T(rand.Rand(glm::uint(params.NumEdges)))) * params.MidAngle; sincos(angXY, ¶ms.X, ¶ms.Y); angMem = angXY; diff --git a/Source/EmberCL/EmberCLFunctions.h b/Source/EmberCL/EmberCLFunctions.h index c21998e..d3097a7 100644 --- a/Source/EmberCL/EmberCLFunctions.h +++ b/Source/EmberCL/EmberCLFunctions.h @@ -174,7 +174,7 @@ static const char* RandFunctionString = "\n" "inline uint MwcNextRange(uint2* s, uint val)\n" "{\n" - " return (val == 0) ? MwcNext(s) : (MwcNext(s) % val);\n" + " return (val == 0) ? MwcNext(s) : (uint)(((ulong)MwcNext(s) * (ulong)val) >> 32);\n" "}\n" "\n" "inline real_t MwcNext01(uint2* s)\n" diff --git a/Source/EmberGenome/EmberGenome.cpp b/Source/EmberGenome/EmberGenome.cpp index b1d9707..5719a13 100644 --- a/Source/EmberGenome/EmberGenome.cpp +++ b/Source/EmberGenome/EmberGenome.cpp @@ -625,7 +625,7 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt) if (opt.CloneAction() != "") os << " " << opt.CloneAction(); - selp0 = embers[rand.Rand() % embers.size()]; + selp0 = embers[rand.Rand(embers.size())]; save = selp0; aselp0 = &selp0; aselp1 = nullptr; @@ -643,7 +643,7 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt) if (doMutate) { - selp0 = embers[rand.Rand() % embers.size()]; + selp0 = embers[rand.Rand(embers.size())]; orig = selp0; aselp0 = &selp0; aselp1 = nullptr; @@ -685,8 +685,8 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt) } else if (doCross0) { - i0 = rand.Rand() % embers.size(); - i1 = rand.Rand() % embers2.size(); + i0 = rand.Rand(embers.size()); + i1 = rand.Rand(embers2.size()); selp0 = embers[i0]; selp1 = embers2[i1]; aselp0 = &selp0; diff --git a/Source/EmberTester/EmberTester.cpp b/Source/EmberTester/EmberTester.cpp index 9a66dbc..6e17a15 100644 --- a/Source/EmberTester/EmberTester.cpp +++ b/Source/EmberTester/EmberTester.cpp @@ -2240,42 +2240,79 @@ int _tmain(int argc, _TCHAR* argv[]) { //int i; bool b = true; + size_t times = 1'000'000'001; + QTIsaac rand; + std::vector vec(16, 0); Timing t(4); - /* vector> fv; - vector> dv; - list> fl; - list> dl; - int w = 1000, h = 1000; - string filename = ".\\testexr.exr"; - vector pixels; - pixels.resize(w * h); + /* + for (size_t i = 1; i < times; i++) + { + auto res = rand.Rand() % i; + vec[res & 15]++; + } - for (auto& pix : pixels) - { - pix.r = 1.0; - pix.b = 0.0; - pix.a = 1.0; - //pix.r = std::numeric_limits::max(); - } + t.Toc("rand mod"); - writeRgba1(filename.c_str(), pixels.data(), w, h); - TestFuncs(); - string line = "title=\"cj_aerie\" smooth=no", delim = " =\""; - auto vec = Split(line, delim, true); + for (auto& it : vec) + { + cout << it / (double)times << endl; + it = 0; + } - for (auto& s : vec) cout << s << endl; + cout << "\n\n"; + t.Tic(); - line = "index=0 color=2177354", delim = " ="; - vec = Split(line, delim, true); + for (size_t i = 1; i < times; i++) + { + //auto res = (uint)(((size_t)rand.Rand() * i) >> 32); + auto res = rand.Rand(i); + vec[res & 15]++; + } - for (auto& s : vec) cout << s << endl; + t.Toc("rand mult shift"); + + for (auto& it : vec) + { + cout << it / (double)times << endl; + it = 0; + } + + return 1; + vector> fv; + vector> dv; + list> fl; + list> dl; + int w = 1000, h = 1000; + string filename = ".\\testexr.exr"; + vector pixels; + pixels.resize(w * h); + + for (auto& pix : pixels) + { + pix.r = 1.0; + pix.b = 0.0; + pix.a = 1.0; + //pix.r = std::numeric_limits::max(); + } + + writeRgba1(filename.c_str(), pixels.data(), w, h); + TestFuncs(); + string line = "title=\"cj_aerie\" smooth=no", delim = " =\""; + auto vec = Split(line, delim, true); + + for (auto& s : vec) cout << s << endl; + + line = "index=0 color=2177354", delim = " ="; + vec = Split(line, delim, true); + + for (auto& s : vec) cout << s << endl; - EmberContainerTester::TestEmberContainer(fv); - EmberContainerTester::TestEmberContainer(dv); - EmberContainerTester::TestEmberContainer(fl); - EmberContainerTester::TestEmberContainer(dl); - CopyCont(fv, fl); + EmberContainerTester::TestEmberContainer(fv); + EmberContainerTester::TestEmberContainer(dv); + EmberContainerTester::TestEmberContainer(fl); + EmberContainerTester::TestEmberContainer(dl); + CopyCont(fv, fl); */ //QTIsaac rand(1, 2, 3); //mt19937 meow(1729);