planner: remove Bühlmann factor cache

The Bühlmann factors were cached in a thread-safe hashmap. It seemed
somewhat dubious that entering a critical section and doing a hash-lookup
would be significantly faster than a simple exp() call.

Indeed, in a very cache friendly test (16 entries, tight loop) calling the
factor() function 32 000 000 times from a different translation units we get:
  - with cache: 604 ms
  - without cache: 266 ms
Therefore, remove the cache. Given that 32 000 000 calls take only 266 ms,
it appears not sensible to try to optimize this function anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-05-05 22:24:50 +02:00 committed by Robert C. Helling
parent f37f428762
commit 123937901f
3 changed files with 6 additions and 47 deletions

View file

@ -290,18 +290,10 @@ double tissue_tolerance_calc(struct deco_state *ds, const struct dive *dive, dou
} }
/* /*
* Return buelman factor for a particular period and tissue index. * Return Buehlmann factor for a particular period and tissue index.
*
* We cache the factor, since we commonly call this with the
* same values... We have a special "fixed cache" for the one second
* case, although I wonder if that's even worth it considering the
* more general-purpose cache.
*/ */
static double factor(int period_in_seconds, int ci, enum inertgas gas) static double factor(int period_in_seconds, int ci, enum inertgas gas)
{ {
double factor;
if (period_in_seconds == 1) { if (period_in_seconds == 1) {
if (gas == N2) if (gas == N2)
return buehlmann_N2_factor_expositon_one_second[ci]; return buehlmann_N2_factor_expositon_one_second[ci];
@ -309,17 +301,11 @@ static double factor(int period_in_seconds, int ci, enum inertgas gas)
return buehlmann_He_factor_expositon_one_second[ci]; return buehlmann_He_factor_expositon_one_second[ci];
} }
factor = cache_value(ci, period_in_seconds, gas); // ln(2)/60 = 1.155245301e-02
if (!factor) { if (gas == N2)
// ln(2)/60 = 1.155245301e-02 return 1.0 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_N2_t_halflife[ci]);
if (gas == N2) else
factor = 1 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_N2_t_halflife[ci]); return 1.0 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_He_t_halflife[ci]);
else
factor = 1 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_He_t_halflife[ci]);
cache_insert(ci, period_in_seconds, gas, factor);
}
return factor;
} }
static double calc_surface_phase(double surface_pressure, double he_pressure, double n2_pressure, double he_time_constant, double n2_time_constant) static double calc_surface_phase(double surface_pressure, double he_pressure, double n2_pressure, double he_time_constant, double n2_time_constant)

View file

@ -1601,31 +1601,6 @@ char *intdup(int index)
return strdup(tmpbuf); return strdup(tmpbuf);
} }
QHash<int, double> factor_cache;
QReadWriteLock factorCacheLock;
extern "C" double cache_value(int tissue, int timestep, enum inertgas inertgas)
{
double value;
int key = (timestep << 5) + (tissue << 1);
if (inertgas == HE)
++key;
factorCacheLock.lockForRead();
value = factor_cache.value(key);
factorCacheLock.unlock();
return value;
}
extern "C" void cache_insert(int tissue, int timestep, enum inertgas inertgas, double value)
{
int key = (timestep << 5) + (tissue << 1);
if (inertgas == HE)
++key;
factorCacheLock.lockForWrite();
factor_cache.insert(key, value);
factorCacheLock.unlock();
}
extern "C" void print_qt_versions() extern "C" void print_qt_versions()
{ {
printf("%s\n", qPrintable(QStringLiteral("built with Qt Version %1, runtime from Qt Version %2").arg(QT_VERSION_STR).arg(qVersion()))); printf("%s\n", qPrintable(QStringLiteral("built with Qt Version %1, runtime from Qt Version %2").arg(QT_VERSION_STR).arg(qVersion())));

View file

@ -146,8 +146,6 @@ const char *subsurface_user_agent();
enum deco_mode decoMode(); enum deco_mode decoMode();
int parse_seabear_header(const char *filename, char **params, int pnr); int parse_seabear_header(const char *filename, char **params, int pnr);
char *get_current_date(); char *get_current_date();
double cache_value(int tissue, int timestep, enum inertgas gas);
void cache_insert(int tissue, int timestep, enum inertgas gas, double value);
void print_qt_versions(); void print_qt_versions();
void lock_planner(); void lock_planner();
void unlock_planner(); void unlock_planner();