用于稀疏,惰性,不可变数组的线程安全缓存

时间:2012-05-08 16:29:05

标签: c caching immutability glib sparse-array

我有一个应用程序涉及一个可能非常大的数组集合(索引最大值为int),但 lazy - 它们的内容被计算在飞行中,直到被要求才真正知道。数组也是不可变的 - 每个数组的每个元素的值在程序的整个生命周期中都是不变的。在某种意义上,数组是稀疏,通常只请求所有数组元素的一小部分(数组不包含大的零块,并且在这种意义上不是“稀疏的”。)

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

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

其中data作为每个数组的唯一句柄(可能有很多这样的句柄)。 point_cache_fetch()应该使用相同的valuepoint_cache_store()参数返回传递给data的{​​{1}}参数,或者通过返回特殊值{{1来指示缓存未命中(调用者永远不会使用idx调用DATUM_UNKNOWN_VALUE)。

问题是:如何实施point_cache_storeDATUM_UNKNOWN_VALUE ? (它们目前是无操作存根。)

要考虑的要点:

  • 缓存实现必须是线程安全的。多个线程同时运行,其中任何一个都可以使用point_cache_fetch()point_cache_store()个参数调用point_cache_store()point_cache_fetch()
  • 缓存真的是一个缓存;即使{1}}知道该值,data也可以返回idx。在这种情况下,调用者只会执行普通查找。
  • 请记住,数组是不可变的 - 对于给定的point_cache_fetch()DATUM_UNKNOWN_VALUE参数,调用者将始终提供相同的data参数。

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

idx

函数valuegit clone git://github.com/gbenison/starparse git clone git://github.com/gbenison/burrow-owl.git -b point-cache-base 可在“burrow / spectrum / point_cache.c”中找到。相关基准是“基准/ b_cache”。

1 个答案:

答案 0 :(得分:0)

“非常大的稀疏懒数组”?听起来你需要hash table

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

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