gpt4 book ai didi

c++ - 没有意义的 CPU 测量(缓存未命中/命中)

转载 作者:行者123 更新时间:2023-11-27 22:58:23 29 4
gpt4 key购买 nike

我使用 Intel PCM 进行细粒度的 CPU 测量。在我的代码中,我试图测量缓存效率。

基本上,我首先将一个小数组放入 L1 缓存(通过多次遍历),然后启动计时器,再遍历数组一次(希望使用缓存),然后关闭计时器。

PCM 显示我的 L2 和 L3 未命中率相当高。我还检查了 rdtscp,每个数组操作的周期为 15(这比访问 L1 缓存的 4-5 个周期高得多)。

我希望数组完全放在 L1 缓存中,我不会有高 L1、L2 和 L3 未命中率。

我的系统L1、L2、L3分别有32K、256K、25M。这是我的代码:

static const int ARRAY_SIZE = 16;

struct MyStruct {
struct MyStruct *next;
long int pad;
}; // each MyStruct is 16 bytes

int main() {
PCM * m = PCM::getInstance();
PCM::ErrorCode returnResult = m->program(PCM::DEFAULT_EVENTS, NULL);
if (returnResult != PCM::Success){
std::cerr << "Intel's PCM couldn't start" << std::endl;
exit(1);
}

MyStruct *myS = new MyStruct[ARRAY_SIZE];

// Make a sequential liked list,
for (int i=0; i < ARRAY_SIZE - 1; i++){
myS[i].next = &myS[i + 1];
myS[i].pad = (long int) i;
}
myS[ARRAY_SIZE - 1].next = NULL;
myS[ARRAY_SIZE - 1].pad = (long int) (ARRAY_SIZE - 1);

// Filling the cache
MyStruct *current;
for (int i = 0; i < 200000; i++){
current = &myS[0];
while ((current = current->n) != NULL)
current->pad += 1;
}

// Sequential access experiment
current = &myS[0];
long sum = 0;

SystemCounterState before = getSystemCounterState();

while ((current = current->n) != NULL) {
sum += current->pad;
}

SystemCounterState after = getSystemCounterState();

cout << "Instructions per clock: " << getIPC(before, after) << endl;
cout << "Cycles per op: " << getCycles(before, after) / ARRAY_SIZE << endl;
cout << "L2 Misses: " << getL2CacheMisses(before, after) << endl;
cout << "L2 Hits: " << getL2CacheHits(before, after) << endl;
cout << "L2 hit ratio: " << getL2CacheHitRatio(before, after) << endl;
cout << "L3 Misses: " << getL3CacheMisses(before_sstate,after_sstate) << endl;
cout << "L3 Hits: " << getL3CacheHits(before, after) << endl;
cout << "L3 hit ratio: " << getL3CacheHitRatio(before, after) << endl;

cout << "Sum: " << sum << endl;
m->cleanup();
return 0;
}

这是输出:

Instructions per clock: 0.408456
Cycles per op: 553074
L2 Cache Misses: 58775
L2 Cache Hits: 11371
L2 cache hit ratio: 0.162105
L3 Cache Misses: 24164
L3 Cache Hits: 34611
L3 cache hit ratio: 0.588873

编辑:我还检查了以下代码,仍然得到相同的未命中率(我希望得到几乎为零的未命中率):

SystemCounterState before = getSystemCounterState();
// this is just a comment
SystemCounterState after = getSystemCounterState();

编辑 2:正如有人评论的那样,这些结果可能是由于探查器本身的开销造成的。所以我不再只一次,而是多次更改代码遍历数组(200,000,000 次),以分摊探查器的开销。我仍然得到非常低的 L2 和 L3 缓存比率 (%15)。

最佳答案

您的系统上的所有内核似乎都出现了 l2 和 l3 未命中

我在这里查看 PCM 实现:https://github.com/erikarn/intel-pcm/blob/ecc0cf608dfd9366f4d2d9fa48dc821af1c26f33/src/cpucounters.cpp

[1] 在第 1407 行的 PCM::program() 实现中,我没有看到任何将事件限制到特定进程的代码

[2] 在第 2809 行的 PCM::getSystemCounterState() 实现中,您可以看到事件是从系统上的所有内核收集的。所以我会尝试将进程的 cpu 亲和性设置为一个核心,然后只从这个核心读取事件 - 使用这个函数 CoreCounterState getCoreCounterState(uint32 core)

关于c++ - 没有意义的 CPU 测量(缓存未命中/命中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30270741/

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