如果多次读取而不卸载内核对象,Arm-v8 PMCCNTR_EL0 将返回 0
我有一个具有多个 A72 核心的 CPU。
我正在尝试对算法进行基准测试,并且想计算线程执行期间经过的核心周期数。
我交叉编译了两个内核对象以正确配置寄存器以访问 PMCCNTR_EL0 : https://github.com/rdolbeau/enable_arm_pmu
https://github.com/jerinjacobk/armv8_pmu_cycle_counter_el0
显然,两者都应该做相同的事情,所以我一次只加载一个,我已经编译了两者,因为我还没有找到完美工作的解决方案目前。
这是我试图测试的代码(例如目的,只是为了尝试寄存器读取)。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include "armpmu_lib.h"
uint64_t tmp = 35000;
uint64_t t0_start = 0;
uint64_t t0_stop = 0;
uint64_t t1_start = 0;
uint64_t t1_stop = 0;
uint64_t t2_start = 0;
uint64_t t2_stop = 0;
void * thread_1(){
//Set core affinity and priority
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(1,&my_set);
sched_setaffinity(0,sizeof(cpu_set_t),&my_set);
struct sched_param param= {
.sched_priority=99
};
sched_setscheduler(0,SCHED_FIFO,¶m);
sleep(1);
//Bench
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(t1_start));
for(int i=0; i<4000; i++){
tmp+=1;
//printf("Thread 1\n");
}
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(t1_stop));
return NULL;
}
void * thread_2(){
//Set core affinity and priority
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(8,&my_set);
sched_setaffinity(0,sizeof(cpu_set_t),&my_set);
struct sched_param param= {
.sched_priority=0
};
sched_setscheduler(0,SCHED_FIFO,¶m);
//Bench
sleep(1);
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(t2_start));
for(int i=0; i<4000; i++){
//printf("Thread 2\n");
tmp+=5;
}
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(t2_stop));
return NULL;
}
int main(){
//Get the starting point cycle number
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(t0_start));
//Creates threads
pthread_t thread_id_1;
pthread_t thread_id_2;
pthread_create(&thread_id_1, NULL, thread_1, NULL);
pthread_create(&thread_id_2, NULL, thread_2, NULL);
//Wait termination
pthread_join(thread_id_1, NULL);
pthread_join(thread_id_2, NULL);
//Read number of cycles at the end of execution
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(t0_stop));
printf("T0 Execution cycles : %lu\n",t0_stop - t0_start); //Main thread number of cycles
printf("T1 Execution cycles : %lu\n",t1_stop - t1_start); //Thread 1 number of cycles
printf("T2 Execution cycles : %lu\n",t2_stop - t2_start); //Thread 2 number of cycles
return 0;
}
当我使用此内核模块时:enable_arm_pmu
如果未加载,则会出现非法指令错误,这是预期的 当我运行存储库上给出的测试代码时,它可以正常工作(我有一致的非零值)。 如果加载,那么我运行我的代码一次,主线程有极值(FFFFFFFFFFDDA4A0 或 O),而其余线程的值似乎是正确的(10 到 25us 之间)。
但是,如果我在没有卸载、重新加载内核模块的情况下多次运行我的工作台,则线程 1 和线程 2 的所有后续执行测量为 0 个周期。
我是否遗漏了寄存器配置中的某些点?
当使用armv8_pmu_cycle_counter_el0内核对象时,主线程的周期数值似乎是正确的(5到10毫秒),但是两个线程都返回0个执行周期。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论