为了对你编写的C++循环代码进行profile并计算每次循环消耗的指令周期数,可以采用以下步骤:
- 使用硬件性能计数器
使用 rdtsc 指令
rdtsc(读时间戳计数器)指令可以返回一个64位时间戳计数器的值,这个计数器从系统启动时开始计数,可以用于非常精确的时间测量。你可以在循环的起点和终点分别调用它,然后计算差值来了解每次迭代所消耗的周期数。
#include <iostream>
#include <memory.h>
#include <string.h>
#include <cstdint>inline uint64_t rdtsc() {unsigned int lo, hi;// Serialize__asm__ __volatile__ ("cpuid" : : : "%rax", "%rbx", "%rcx", "%rdx");// Get the time-stamp counter__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));return (static_cast<uint64_t>(hi) << 32) | lo;
}void profiled_loop(int v[], int iterations, int &n, int r[]) {uint64_t start = rdtsc();for (int i = 0; i < iterations; ++i) {
#if 0if (v[i] < 1) { r[n++] = i; }
#elser[n] = i; n += (v[i] < 1);
#endif}uint64_t end = rdtsc();std::cout << "Cycles per iteration: "<< (end - start) / static_cast<double>(iterations)<< std::endl;
}int main() {const int iterations = 100000000; // Number of loop iterationsint *v = (int *)malloc(sizeof(int) * iterations);int *k = (int *)malloc(sizeof(int) * iterations);memset(v, sizeof(int) * iterations, 0);memset(k, sizeof(int) * iterations, 0);int n = 0;for (int i = 0; i < iterations; ++i) {v[i] = (i % 5 == 0);}profiled_loop(v, iterations, n, k);std::cout << n << std::endl;return 0;
}
- 高级分析工具
使用 perf 工具 (Linux)
perf 是一个 Linux 性能分析工具,可以对运行时程序进行详细的硬件事件分析,例如 CPU cycles。
编译你的程序:
g++ -o my_program my_program.cpp
使用 perf 工具运行你的程序并收集数据:
perf stat ./my_program
perf stat 将会报告各种性能计数,包括指令周期数。