gpt4 book ai didi

c++ - LRU 缓存和多线程

转载 作者:太空宇宙 更新时间:2023-11-04 11:57:22 33 4
gpt4 key购买 nike

我前段时间已经发帖询问LRU缓存的良好设计(C++)。您可以在此处找到问题、答案和一些代码:

Better understanding the LRU algorithm

我现在尝试对这段代码进行多线程处理(使用 pthread),并得到了一些意想不到的结果。在尝试使用锁定之前,我已经创建了一个系统,其中每个线程都访问自己的缓存(参见代码)。我在 4 核处理器上运行这段代码。我尝试用 1 个线程和 4 个线程运行它。当它在 1 个线程上运行时,我在缓存中执行 100 万次查找,在 4 个线程上,每个线程执行 250K 次查找。我期望通过 4 个线程减少时间,但结果恰恰相反。 1个线程运行2.2秒,4个线程运行6秒多??我只是无法理解这个结果。

我的代码有问题吗?这能以某种方式解释吗(线程管理需要时间)。如果能得到专家的反馈,那就太好了。非常感谢-

我用以下代码编译这段代码:c++ -o cache cache.cpp -std=c++0x -O3 -lpthread

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>
#include <sys/time.h>

#include <list>

#include <cstdlib>
#include <cstdio>
#include <memory>
#include <list>
#include <unordered_map>

#include <stdint.h>
#include <iostream>

typedef uint32_t data_key_t;

using namespace std;
//using namespace std::tr1;

class TileData
{
public:
data_key_t theKey;
float *data;
static const uint32_t tileSize = 32;
static const uint32_t tileDataBlockSize;
TileData(const data_key_t &key) : theKey(key), data(NULL)
{
float *data = new float [tileSize * tileSize * tileSize];
}
~TileData()
{
/* std::cerr << "delete " << theKey << std::endl; */
if (data) delete [] data;
}
};

typedef shared_ptr<TileData> TileDataPtr; // automatic memory management!

TileDataPtr loadDataFromDisk(const data_key_t &theKey)
{
return shared_ptr<TileData>(new TileData(theKey));
}

class CacheLRU
{
public:
list<TileDataPtr> linkedList;
unordered_map<data_key_t, TileDataPtr> hashMap;
CacheLRU() : cacheHit(0), cacheMiss(0) {}
TileDataPtr getData(data_key_t theKey)
{
unordered_map<data_key_t, TileDataPtr>::const_iterator iter = hashMap.find(theKey);
if (iter != hashMap.end()) {
TileDataPtr ret = iter->second;
linkedList.remove(ret);
linkedList.push_front(ret);
++cacheHit;
return ret;
}
else {
++cacheMiss;
TileDataPtr ret = loadDataFromDisk(theKey);
linkedList.push_front(ret);
hashMap.insert(make_pair<data_key_t, TileDataPtr>(theKey, ret));
if (linkedList.size() > MAX_LRU_CACHE_SIZE) {
const TileDataPtr dropMe = linkedList.back();
hashMap.erase(dropMe->theKey);
linkedList.remove(dropMe);
}
return ret;
}

}
static const uint32_t MAX_LRU_CACHE_SIZE = 100;
uint32_t cacheMiss, cacheHit;
};

int numThreads = 1;

void *testCache(void *data)
{
struct timeval tv1, tv2;
// Measuring time before starting the threads...
double t = clock();
printf("Starting thread, lookups %d\n", (int)(1000000.f / numThreads));
CacheLRU *cache = new CacheLRU;
for (uint32_t i = 0; i < (int)(1000000.f / numThreads); ++i) {
int key = random() % 300;
TileDataPtr tileDataPtr = cache->getData(key);
}
std::cerr << "Time (sec): " << (clock() - t) / CLOCKS_PER_SEC << std::endl;
delete cache;
}

int main()
{
int i;
pthread_t thr[numThreads];
struct timeval tv1, tv2;
// Measuring time before starting the threads...
gettimeofday(&tv1, NULL);
#if 0
CacheLRU *c1 = new CacheLRU;
(*testCache)(c1);
#else
for (int i = 0; i < numThreads; ++i) {
pthread_create(&thr[i], NULL, testCache, (void*)NULL);
//pthread_detach(thr[i]);
}

for (int i = 0; i < numThreads; ++i) {
pthread_join(thr[i], NULL);
//pthread_detach(thr[i]);
}
#endif

// Measuring time after threads finished...
gettimeofday(&tv2, NULL);

if (tv1.tv_usec > tv2.tv_usec)
{
tv2.tv_sec--;
tv2.tv_usec += 1000000;
}

printf("Result - %ld.%ld\n", tv2.tv_sec - tv1.tv_sec,
tv2.tv_usec - tv1.tv_usec);

return 0;
}

最佳答案

一千次道歉,通过不断调试代码,我意识到我犯了一个非常严重的初学者错误,如果你看一下这段代码:

TileData(const data_key_t &key) : theKey(key), data(NULL)
{
float *data = new float [tileSize * tileSize * tileSize];
}

来自 TikeData 类,其中数据实际上应该是该类的成员变量...所以正确的代码应该是:

class TileData
{
public:
float *data;
TileData(const data_key_t &key) : theKey(key), data(NULL)
{
data = new float [tileSize * tileSize * tileSize];
numAlloc++;
}
};

对此我感到非常抱歉!这是我过去犯过的错误,我想原型(prototype)制作很棒,但有时会导致犯下这种愚蠢的错误。我用 1 个和 4 个线程运行代码,现在确实看到了加速。 1 个线程大约需要 2.3 秒,4 个线程需要 0.92 秒。感谢大家的帮助,如果我让你耽误了时间,我深表歉意;-)

关于c++ - LRU 缓存和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15634795/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com