我需要在 3D 渲染器中实现 LRU 算法以进行纹理缓存。我在 Linux 上用 C++ 编写代码。
在我的例子中,我将使用纹理缓存来存储图像数据的“图块”(16x16 像素块)。现在想象一下,我在缓存中进行查找,得到一个命中(图块在缓存中)。如何将该条目的“缓存”内容返回给函数调用者?我解释。我想当我在缓存中加载一个图块时,我分配内存来存储 16x16 像素,然后加载该图块的图像数据。现在有两种解决方案将缓存条目的内容传递给函数调用者:
1)作为指向切片数据的指针(快速,内存高效),TileData *tileData = cache->lookup(tileId); // 不安全?
2)或者我需要在函数调用者分配的内存空间内从缓存中重新复制切片数据(复制可能很慢)。
无效缓存::lookup(int tileId, float *&tileData) { // 在缓存中查找切片,如果不在缓存中,则从磁盘加载到缓存,... ... // 现在复制平铺数据,安全但不是很慢吗? memcpy((char*)tileData, tileDataFromCache, sizeof(float) * 3 * 16 * 16); } 浮动 *tileData = 新浮动[3 * 16 * 16]; // 需要为该图块分配内存 // 从缓存中获取瓦片数据,需要一个副本 缓存->查找(tileId,tileData);
我会选择 1),但问题是,如果在查找之后将切片从缓存中删除,并且该函数尝试使用返回指针访问数据,会发生什么情况?我看到的唯一解决方案是使用一种引用计数(auto_ptr)的形式,其中数据实际上仅在不再使用时才被删除?
应用程序可能会访问超过 1 个纹理。我似乎找不到一种方法来创建每个纹理和纹理的每个图块都是唯一的密钥。例如,我可能在缓存中有来自 file1 的 tile 1 和来自 file2 的 tile1,因此在 tildId=1 上进行搜索是不够的......但我似乎无法找到一种方法来创建该文件的密钥名称和 tileID。我可以构建一个包含文件名和 tileID (FILENAME_TILEID) 的字符串,但用作键的字符串不会比整数慢得多吗?
最后我有一个关于时间戳的问题。许多论文建议使用时间戳来对缓存中的条目进行排序。使用时间戳有什么好的功能?时间()函数,时钟()?有没有比使用时间戳更好的方法?
抱歉,我意识到这是一条很长的消息,但是 LRU 的实现似乎并不像听起来那么简单。