0

我有一个应用程序,它涉及一个数组集合,这些数组可能非常大(索引达到 an 的最大值int),但它们是惰性的 - 它们的内容是动态计算的,在请求之前实际上并不知道。数组也是不可变的——每个数组的每个元素的值在程序的整个生命周期中都是恒定的。从某种意义上说,数组是稀疏的,因为通常只请求所有数组元素的一小部分(数组不包含大的零块,并且在这个意义上不是“稀疏”的。)

查找(并可能在此过程中计算)数组元素可能很昂贵,因此我想添加一个缓存层。缓存应实现以下接口:

void point_cache_store (gpointer data, gsize idx, gdouble value);
gdouble point_cache_fetch (gpointer data, gsize idx);

wheredata作为每个数组的唯一句柄(可以有很多)。 point_cache_fetch()应该返回value传递给的参数point_cache_store()data参数idx,或者通过返回特殊值来指示缓存未命中DATUM_UNKNOWN_VALUE(调用者永远不会point_cache_store用调用DATUM_UNKNOWN_VALUE)。

问题是:我怎样才能实现point_cache_fetch()point_cache_store()?(它们目前是无操作存根。)

需要考虑的要点:

  • 缓存实现必须是线程安全的。几个线程同时运行,其中任何一个都可以调用point_cache_store()point_cache_fetch()使用任何dataidx参数。
  • 缓存确实是缓存;point_cache_fetch()return总是可以的DATUM_UNKNOWN_VALUE,即使它曾经知道那个值。在这种情况下,调用者将只执行普通查找。
  • 请记住,数组是不可变的——对于给定的参数dataidx参数,调用者将始终提供相同的value参数。

我意识到有很多方法可以做到这一点,并且需要权衡取舍。不过,对于这个问题,我将通过一个非常具体的标准来评估答案:它们是否会提高启发该问题的应用程序中某个特定基准的性能。如果您想加倍努力并自己运行基准测试,请执行以下操作:

git clone git://github.com/gbenison/starparse
git clone git://github.com/gbenison/burrow-owl.git -b point-cache-base

函数point_cache_fetch()point_cache_store()位于“burrow/spectrum/point_cache.c”中。相关的基准是“benchmarks/b_cache”。

4

1 回答 1

0

“非常大的稀疏惰性数组”?听起来你需要一个哈希表

从您的point_cache_fetch函数原型和整个问题中,我对您的缓存值是双精度数组还是不可变数组感到困惑。

我不打算提供一个实现,因为这不是一个“编码挑战”网站。您应该尝试查找和重用现有的线程安全哈希表库,并根据您的特定需求比较它们的性能。

于 2012-05-16T13:53:56.200 回答