【发布时间】:2011-09-19 22:23:40
【问题描述】:
当我在一些原始图像处理操作中尝试使用 SIMD 指令内在函数时,我正在构建一个微基准来测量性能变化。但是,编写有用的微基准很困难,所以我想首先了解(并尽可能消除)尽可能多的变化和错误来源。
我必须考虑的一个因素是测量代码本身的开销。我正在使用 RDTSC 进行测量,并且正在使用以下代码来查找测量开销:
extern inline unsigned long long __attribute__((always_inline)) rdtsc64() {
unsigned int hi, lo;
__asm__ __volatile__(
"xorl %%eax, %%eax\n\t"
"cpuid\n\t"
"rdtsc"
: "=a"(lo), "=d"(hi)
: /* no inputs */
: "rbx", "rcx");
return ((unsigned long long)hi << 32ull) | (unsigned long long)lo;
}
unsigned int find_rdtsc_overhead() {
const int trials = 1000000;
std::vector<unsigned long long> times;
times.resize(trials, 0.0);
for (int i = 0; i < trials; ++i) {
unsigned long long t_begin = rdtsc64();
unsigned long long t_end = rdtsc64();
times[i] = (t_end - t_begin);
}
// print frequencies of cycle counts
}
运行此代码时,我得到如下输出:
Frequency of occurrence (for 1000000 trials):
234 cycles (counted 28 times)
243 cycles (counted 875703 times)
252 cycles (counted 124194 times)
261 cycles (counted 37 times)
270 cycles (counted 2 times)
693 cycles (counted 1 times)
1611 cycles (counted 1 times)
1665 cycles (counted 1 times)
... (a bunch of larger times each only seen once)
我的问题是:
- 以上代码产生的循环计数双峰分布的可能原因是什么?
- 为什么最快的时间(234 个周期)只出现少数几次 - 什么极不寻常的情况会减少计数?
更多信息
平台:
- Linux 2.6.32 (Ubuntu 10.04)
- g++ 4.4.3
- 酷睿2双核(E6600);这具有恒定速率 TSC。
SpeedStep 已关闭(处理器设置为性能模式并以 2.4GHz 运行);如果在“按需”模式下运行,我会在 243 和 252 个周期处获得两个峰值,在 360 和 369 个周期处有两个(可能是对应的)峰值。
我正在使用sched_setaffinity 将进程锁定到一个核心。如果我在每个内核上依次运行测试(即锁定到内核 0 并运行,然后锁定到内核 1 并运行),我得到两个内核的相似结果,除了 234 个周期的最快时间往往会稍微出现核心 1 上的次数少于核心 0 上的次数。
编译命令为:
g++ -Wall -mssse3 -mtune=core2 -O3 -o test.bin test.cpp
GCC 为核心循环生成的代码是:
.L105:
#APP
# 27 "test.cpp" 1
xorl %eax, %eax
cpuid
rdtsc
# 0 "" 2
#NO_APP
movl %edx, %ebp
movl %eax, %edi
#APP
# 27 "test.cpp" 1
xorl %eax, %eax
cpuid
rdtsc
# 0 "" 2
#NO_APP
salq $32, %rdx
salq $32, %rbp
mov %eax, %eax
mov %edi, %edi
orq %rax, %rdx
orq %rdi, %rbp
subq %rbp, %rdx
movq %rdx, (%r8,%rsi)
addq $8, %rsi
cmpq $8000000, %rsi
jne .L105
【问题讨论】:
-
我自己的测量代码得到了完全相同的差异
-
@drhirsch:很高兴知道。你能说一下你测量的是什么 CPU,在方法上是否有任何重大差异?
-
Core 2 Q9550,6600 的 45 nm 版本。我接受了 243 的值,我知道我测量了很多废话
-
根据ccsl.carleton.ca/~jamuir/rdtscpm1.pdf ,CPUID 有烦人的可变延迟。您可以尝试在没有 CPUID 的情况下重复。如果您的处理器支持,显然还有 RDTSCP 正在序列化。
-
@tc:感谢您的链接——我想我在其他地方找到了对那篇文章的引用,但它的链接已损坏。
标签: c++ performance assembly intel rdtsc