Я использую perf_event_open (), чтобы измерить частоту пропадания кэша. Я делаю это следующим образом:
double cachemiss(int PID_NUM){
int i;double rate;
struct perf_event_attr pe;
int fd1,fd2;
uint64_t miss,reference;
uint64_t id1, id2;
struct read_format buf;
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_CACHE_MISSES;
pe.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
fd1 = perf_event_open(&pe, PID_NUM, -1, -1, 0);
ioctl(fd1, PERF_EVENT_IOC_ID, &id1);
if (fd1 == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_CACHE_REFERENCES;
pe.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
fd2 = perf_event_open(&pe, PID_NUM, -1, fd1, 0);
ioctl(fd2, PERF_EVENT_IOC_ID, &id2);
if (fd2 == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
ioctl(fd1, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
ioctl(fd1, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
usleep(10000);
ioctl(fd1, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);
read(fd1, &buf, sizeof(buf));
for (i = 0; i < buf.nr; i++) {
if (buf.values[i].id == id1) miss = buf.values[i].value;
else if (buf.values[i].id == id2) reference =buf.values[i].value;
}
rate=(double)miss/((((double)reference+(double)miss))+1);
return rate;
}
int main()
{
for(int i=0;1;i++) cout<<i<<"\t"<<cachemiss(11);
}
Тогда в начале 509 раз нет ничего плохого. Но когда дело доходит до 510-го раза, fd2 = -1. Я пробую это снова и снова, но проблема всегда одна и та же: 510 раз не работает.