preempt_disable / enable和raw_local_irq_save / restore在基准测试中的作用

时间:2018-01-23 04:24:03

标签: c++ c kernel benchmarking inline-assembly

英特尔(link)的以下论文描述了一种准确对代码进行基准测试的方法。基准测试的核心内容如下(参见第31页):

preempt_disable();
raw_local_irq_save(flags);

asm volatile ( 
    "CPUID\n\t" 
    "RDTSC\n\t" 
    "mov %%edx, %0\n\t" 
    "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"
);

/*call the function to measure here*/ 

asm volatile( 
    "CPUID\n\t" 
    "RDTSC\n\t" 
    "mov %%edx, %0\n\t"
    "mov %%eax, %1\n\t": "=r" (cycles_high1), "=r" (cycles_low1):: "%rax", "%rbx", "%rcx", "%rdx"
); 

raw_local_irq_restore(flags);  
preempt_enable(); 

我在想:

  • raw_local_irq_saveraw_local_irq_restore做什么?
  • preempt_disablepreempt_enable做什么?
  • 他们在特定背景下的角色是什么?
  • 从基准测试代码中删除它们会产生什么后果?会阻止正确的基准测试吗?什么可能出错?

1 个答案:

答案 0 :(得分:4)

在您提供的链接中,如果您阅读第2.2节,他们实际实现了内核模块,您可以看到有一些注释 -

.join

这是一个Linux内核function,它基本上禁止处理器将上下文切换到不同的进程。

第二个电话 -

preempt_disable(); /*we disable preemption on our CPU*/

这会屏蔽硬件上的所有中断。又一个Linux内核function

这两者一起暗示在基准测试完成之前,甚至硬件中断都不会干扰处理器。这是为了确保对处理器和其他资源(如缓存,TLB等)的独占访问。我假设您可以理解为什么这对于正确的基准测试是必要的。

其他两个函数,正如其名称所示,在基准测试完成后重新启用抢占并恢复中断掩码。

至于将会发生什么,如果这些调用被删除,那么“某些东西”可能会中断您的基准测试过程,并且您的测量值会出现非常大的差异。