Skip to content
amirroth edited this page Sep 20, 2021 · 5 revisions

So ... what is up with this “caching” business? You know, the thing we do for some psychrometric functions. What does caching do? How is it supposed to work? The idea behind caching is to reuse computations rather than recomputing. Caching works well for computations that:

  • Are functions, i.e., the outputs depend only on the inputs and there are no “destructive” side-effects.
  • Do enough work such that looking up a precomputed value in a table is significantly faster than re-computing.
  • Have relatively few inputs, the more inputs, the more difficult it is to organize a table to hold computed results.

The psychrometric functions are good examples of this, so we will use them as “mules”. One of the simplest mules is PsyTsatFnPb, which has a single input, the barometric pressure:

Real64 PsyTsatFnPb(Real64 Pb);

A cached version of PsyTsatFnPb uses of an array of structs:

struct TsatCache_t { Real64 Pb_tag; Real 64 Tsat; }

int constexpr tsat_cache_size = 1024 * 1024;
std::array<struct TsatCache_t, tsat_cache_size> Tsat_cache;

And the logic of the function is:

  • Search the array for an entry in which Pb_Tag matches the Pb input
  • If found return Tsat from same entry
  • If not found, create new entry where Pb_Tag is Pb and Tsat is computed using the existing PsyTsatFnPb function

Simple, right? Well, the key obvious is making the array search very efficient. This:

for (int i = 0; i < tsat_cache_size; ++i) {
   if (Tsat_cache[i] Pb_tag == Pb) {
      return Tsat_cache[i].Tsat;
   }
}

is just not going to cut it. Not only is it potentially much slower than just computing PsyTsatFnPb, but where do we put the new entry if we don’t find it already in there? The key to effective caching is the “index function”, a function that (usually) maps the inputs to the index in the cache array where the entry is found. The actual logic is much more like this.

int index = index_function(Pb);
if (Tsat_cache[index].Pb_tag != Pb) {
   Tsat_cache[index].Pb_tag = Pb
   Tsat_cache[index].Tsat = PsyTsatFnPb(Pb);
}
return Tsat_cache[index].Tsat;
Clone this wiki locally