ARM PMU周期计数器的值不一致

问题描述 投票:0回答:1

我正在尝试使用pmu评估我在Linux内核中的代码的性能。首先,我要测试pmu,因此在内核中创建了简单的夫妇操作循环。我将其置于具有禁用中断的自旋锁下,因此无法抢占我的测试代码。然后,我打印了周期计数器以检查此循环需要多少CPU周期。但是我看到每张纸都有非常不同的值:100、500、1000、200,...我的问题是:为什么我每次都看到如此不同的价值观?PS:在循环计数器的计数器中,pmu的指令计数器是稳定的,每次都看到相同的值。我也尝试使用arm计时器,但它也显示与pmu的周期计数器相似的不同值。这是我使用ARM计时器来衡量性能的方法:

unsigned long long ticks_start, ticks_end;
int i = 0, j;
unsigned long flags;

spin_lock_irqsave(&lock, flags);
while (i++ < 100) {
   j = 0;
   asm volatile("mrs %0, CNTPCT_EL0" : "=r" (ticks_start)); 
   while (j++ < 10000) {
      asm volatile ("nop");
   }
   asm volatile("mrs %0, CNTPCT_EL0" : "=r" (ticks_end));
   printk("ticks %d are: %llu\n", i, ticks_end - ticks_start);
}
spin_unlock_irqrestore(&lock, flags);

并且在实际设备上的输出是(皮质A-57):

...
ticks 31 are: 2287
ticks 32 are: 2287
ticks 33 are: 2287
ticks 34 are: 1984
ticks 35 are: 457
ticks 36 are: 1604
ticks 37 are: 2287
...

c linux-kernel arm arm64 intel-pmu
1个回答
0
投票

为了在Arm上使用计时器和PMU之类的东西,应该在读取PMU寄存器之前插入isb指令。该体系结构允许处理器提前或延迟推测性读取寄存器,因为它不依赖于nops的内部循环。

因此,请尝试:

asm volatile("isb; mrs %0, CNTPCT_EL0" : "=r" (ticks_end));

isb将在继续执行mrs指令之前刷新管道。 CPU可能也在节流,但这不会影响使用周期计数器的测量,但是如果您正在读取通用计时器来测量时间,则可能会受到影响。

© www.soinside.com 2019 - 2024. All rights reserved.