double experiment(qint64 len, int fdRef, int fdMiss) { std::vector<int> v(len); std::vector<int> vRand(len); int samples = 10; double rate = 0.0; for (int i = 0; i < samples; i++) { long vRefI, vMissI, vRefF, vMissF; int ret = 0; write_linear(v); write_random(vRand); read_linear(v); ret = read(fdRef, &vRefI, sizeof(vRefI)); ret = read(fdMiss, &vMissI, sizeof(vMissI)); read_random(v, vRand); ret = read(fdRef, &vRefF, sizeof(vRefF)); ret = read(fdMiss, &vMissF, sizeof(vMissF)); vMissF -= vMissI; vRefF -= vRefI; double delta = (double)vMissF / vRefF; qDebug() << "ret" << ret << " L1 Cache Accesses: "<< vRefF << " L1 Cache Misses: "<< vMissF <<" value " << delta; rate += delta; } return rate / samples; }
void write_random(std::vector<int> &v) { write_linear(v); std::random_shuffle(v.begin(), v.end()); }
int do_experiment(const CounterTypeEnum::Type type) { perf_event_attr attr; memset(&attr, 0, sizeof(attr)); attr.size = sizeof(attr); /* * General hardware counter * IPC = instruction / cycles * Miss ratio = references / misses */ switch (type) { case CounterTypeEnum::INSTRUCTIONS: attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_INSTRUCTIONS; break; case CounterTypeEnum::CYCLES: attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_CPU_CYCLES; break; case CounterTypeEnum::L1_READ: attr.type = PERF_TYPE_HW_CACHE; attr.config = (PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16); break; case CounterTypeEnum::L1_MISSES: attr.type = PERF_TYPE_HW_CACHE; attr.config = (PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16); break; default: qDebug() << "invalid counter selected"; return -1; } pid_t tid = gettid(); int fd = sys_perf_event_open(&attr, tid, -1, -1, 0); int samples = 10; long sum = 0; int len = 1000; std::vector<int> v(len); std::vector<int> buf(1E6); (void) buf; for (int i = 0; i < samples; i++) { long v1, v2; int ret = 0; // Read the counter value ret = read(fd, &v1, sizeof(v1)); assert(ret > 0); // do some work write_linear(v); // Read the counter value ret = read(fd, &v2, sizeof(v2)); assert(ret > 0); long delta = v2 - v1; qDebug() << CounterTypeEnum::Names[type] << "value" << delta; sum += delta; } qDebug() << CounterTypeEnum::Names[type] << " avg value" << sum / samples; close(fd); return 0; }