我正在使用一个带有包含信息表的外部EEPROM的微控制器.
存在大量信息,但是如果我们相当"稳定",我们很可能会要求相同的信息周期循环 - 例如,如果我们处于恒定温度.
EEPROM读取大约需要1ms,每个周期大约需要30次.我们的周期目前约为100毫秒,因此可以节省大量成本.
因此,我正在考虑实现RAM缓存.由于微控制器内核以8Mhz运行,因此命中速度应明显快于1ms.
查找涉及返回16位数据的16位地址.微控制器是32位的.
任何关于缓存的输入都将非常受欢迎,特别是如果我完全错过了标记并且应该使用其他东西,如链接列表,甚至是预先存在的库.
以下是我认为我想要实现的目标:
- 由一组结构组成的缓存.该结构将包含地址,数据和某种计数器,指示访问此数据的频率(readCount).
- 数组通常按地址排序.我会有一个有效的lookup()函数来查找地址并获取数据(建议?)
- 如果我遇到缓存未命中,我会通过readCount对数组进行排序,以确定最少使用的缓存值并将其丢弃.然后,我将用从EEPROM中查找的新值填充其位置.然后我会按地址重新排序数组.任何排序都会使用有效排序(shell排序? - 不知道如何使用数组处理这个)
- 我会以某种方式将所有readCount变量减少到如果不使用它们将倾向于零.这应该保留经常使用的变量.
到目前为止,这是我的想法(伪代码,为我的编码风格道歉):
#define CACHE_SIZE 50
//one piece of data in the cache
struct cacheItem
{
uint16_t address;
uint16_t data;
uint8_t readCount;
};
//array of cached addresses
struct cacheItem cache[CACHE_SIZE];
//function to get data from the cache
uint16_t getDataFromCache(uint16_t address)
{
uint8_t cacheResult;
struct cacheItem * cacheHit; //Pointer to a successful cache hit
//returns CACHE_HIT if in the cache, else returns CACHE_MISS
cacheResult …Run Code Online (Sandbox Code Playgroud) 似乎无法解决这个问题。简单例子如下:
#include <iostream>
#include <map>
int main() {
std::map<uint32_t, char> m;
m[1] = 'b';
m[3] = 'd';
m[5] = 'f';
std::map<uint32_t, char>::iterator i = m.lower_bound('d');
std::cout << "First: " << i->first << std::endl;
// Decrement the iterator
i--;
// Expect to get 1, but get 5?
std::cout << "Second: " << i->first << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
First: 3
Second: 5
Run Code Online (Sandbox Code Playgroud)
为什么我这里是5?我认为递减迭代器会导致它指向键 1