其他人已经很好地解释了性能差异。我只想补充一点,类似甚至相同的接口在面向对象程序设计中很常见——这是编写面向对象软件的一般方法论的一部分。您决不能因为两个类实现了相同的接口就假设它们以相同的方式工作,就像您不能因为两个类都实现了攻击()和 make _ sound ()就假设一匹马像一条狗一样工作一样。
这里是一个概念验证代码使用的列表,无序映射,给予 O (1)查找和 O (1)确切的 LRU 维护。需要(非擦除的)迭代器来保存擦除操作。计划使用在一个 O (1)任意大的软件管理缓存的 CPU 指针的 GPU 内存。向 Linux O (1)调度程序点头(LRU <-> 每个处理器运行队列)。Unorder _ map 通过哈希表具有常量时间访问权限。
#include <iostream>
#include <list>
#include <unordered_map>
using namespace std;
struct MapEntry {
list<uint64_t>::iterator LRU_entry;
uint64_t CpuPtr;
};
typedef unordered_map<uint64_t,MapEntry> Table;
typedef list<uint64_t> FIFO;
FIFO LRU; // LRU list at a given priority
Table DeviceBuffer; // Table of device buffers
void Print(void){
for (FIFO::iterator l = LRU.begin(); l != LRU.end(); l++) {
std::cout<< "LRU entry "<< *l << " : " ;
std::cout<< "Buffer entry "<< DeviceBuffer[*l].CpuPtr <<endl;
}
}
int main()
{
LRU.push_back(0);
LRU.push_back(1);
LRU.push_back(2);
LRU.push_back(3);
LRU.push_back(4);
for (FIFO::iterator i = LRU.begin(); i != LRU.end(); i++) {
MapEntry ME = { i, *i};
DeviceBuffer[*i] = ME;
}
std::cout<< "************ Initial set of CpuPtrs" <<endl;
Print();
{
// Suppose evict an entry - find it via "key - memory address uin64_t" and remove from
// cache "tag" table AND LRU list with O(1) operations
uint64_t key=2;
LRU.erase(DeviceBuffer[2].LRU_entry);
DeviceBuffer.erase(2);
}
std::cout<< "************ Remove item 2 " <<endl;
Print();
{
// Insert a new allocation in both tag table, and LRU ordering wiith O(1) operations
uint64_t key=9;
LRU.push_front(key);
MapEntry ME = { LRU.begin(), key };
DeviceBuffer[key]=ME;
}
std::cout<< "************ Add item 9 " <<endl;
Print();
std::cout << "Victim "<<LRU.back()<<endl;
}