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



我有一个应用程序,它涉及数组的集合,这些数组可能非常大(索引最多为int的最大值(,但这些数组是惰性的 - 它们的内容是动态计算的,直到请求才真正知道。 数组也是不可变的 - 每个数组的每个元素的值在程序的整个生命周期中都是恒定的。 数组是稀疏的,因为通常只请求所有数组元素的一小部分(数组不包含大的零块,也不是这个意义上的"稀"(。

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

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

其中data充当每个数组的唯一句柄(可以有很多这样的数组(。 point_cache_fetch()应返回具有相同dataidx参数传递给point_cache_store()value参数,或者通过返回特殊值DATUM_UNKNOWN_VALUE来指示缓存未命中(调用方永远不会使用 DATUM_UNKNOWN_VALUE 调用point_cache_store(。

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

需要考虑的要点:

  • 缓存实现必须是线程安全的。 多个线程同时运行,其中任何一个线程都可以使用任何dataidx参数调用point_cache_store()point_cache_fetch()
  • 缓存
  • 确实是一个缓存;point_cache_fetch()返回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"中。 相关基准是"基准/b_cache"。

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

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

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

相关内容

  • 没有找到相关文章