preempt_disable/启用和raw_local_irq_save/恢复在基准测试中的作用
Role of preempt_disable/enable and raw_local_irq_save/restore in benchmarking
英特尔的以下论文(链接)描述了一种准确基准测试代码的方法。基准的核心如下(见第31页):
preempt_disable();
raw_local_irq_save(flags);
asm volatile (
"CPUIDnt"
"RDTSCnt"
"mov %%edx, %0nt"
"mov %%eax, %1nt": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"
);
/*call the function to measure here*/
asm volatile(
"CPUIDnt"
"RDTSCnt"
"mov %%edx, %0nt"
"mov %%eax, %1nt": "=r" (cycles_high1), "=r" (cycles_low1):: "%rax", "%rbx", "%rcx", "%rdx"
);
raw_local_irq_restore(flags);
preempt_enable();
我想知道:
raw_local_irq_save
和raw_local_irq_restore
做什么?preempt_disable
和preempt_enable
做什么?- 它们在这种特定背景下的作用是什么?
- 将它们从基准测试代码中删除会产生什么后果?它会阻止正确的基准测试吗?可能出现什么问题?
在您提供的链接中,如果您阅读他们实际实现内核模块的第 2.2 节,您可以看到有一些评论 -
preempt_disable(); /*we disable preemption on our CPU*/
这是一个 Linux 内核函数,它基本上禁用处理器将上下文切换到不同的进程。
第二个电话——
raw_local_irq_save(flags); /*we disable hard interrupts on our CPU*/
/*at this stage we exclusively own the CPU*/
这会屏蔽硬件上的所有中断。又是另一个 Linux 内核函数。
这两者共同意味着,在基准测试完成之前,任何内容(甚至硬件中断)都不会干扰处理器。这是为了确保对处理器和其他资源(如缓存、TLB 等)的独占访问。我想你可以弄清楚为什么这对于正确的基准测试是必要的。
顾名思义,其他两个函数在基准测试完成后重新启用抢占并恢复中断掩码。
至于会发生什么,如果这些调用被删除,那么"某些东西"可能会中断您的基准测试过程,并且您的测量可能会获得非常高的方差。
相关文章:
- 使用rdtsc进行基准测试的缺点是什么
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 更高效地在微控制器上对C++进行基准测试
- _mm256_load_ps调试模式下导致谷歌/基准测试的分段错误
- 二叉树基准测试结果
- 如何使用谷歌基准测试对自定义界面进行基准测试
- 谷歌基准测试,如何只调用一次代码?
- 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试
- 谷歌基准测试结果中显示的时间没有意义
- 使用 Google 基准测试时返回值会发生什么情况?
- 如何在Qt测试框架中对信号进行基准测试?
- C/C++memcpu基准测试:测量CPU和墙时间
- 如何将参数传递给Google基准测试程序
- 如何对CUDA项目进行基准测试
- 为什么这个简单的 C++ SIMD 基准测试在使用 SIMD 指令时运行速度较慢?
- 多部分基准测试的权重是多少?
- 简单的 for() 循环基准测试在任何循环绑定下花费相同的时间
- 禁用优化后,quick-bench.com 基准测试要快得多
- Winsock本地客户服务器基准测试
- preempt_disable/启用和raw_local_irq_save/恢复在基准测试中的作用