나는 Linux의 Perf와 함께 카운터의 가치를 읽었습니다. 그 가치는 항상 0입니다.

StackOverflow https://stackoverflow.com/questions/19835714

  •  25-07-2022
  •  | 
  •  

문제

나는 Ubuntu 12.04에서 프로그램을 운영하고 있습니다. 카운터의 가치는 Awalys 0입니다. 내 카운터가 나에게 효과가없는 것 같습니다.

프로그램을 운영 할 때 OUPUT는 다음과 같습니다.


Get the number of CPU:8
Create counters for each CPU finished!
run_perf_stat()!
Cache miss in cpu1:0
Cache miss in cpu2:0
Cache miss in cpu3:0
Cache miss in cpu4:0
Cache miss in cpu5:0
Cache miss in cpu6:0
Cache miss in cpu7:0
Cache miss in cpu8:0

나는 가치를 이해할 수 없습니다. 내가 얻고 싶은 것은 모든 CPU의 캐시 참조이며 캐시 미스입니다. 그러나 분명히 결과는 정확하지 않은 것 같습니다!

나는 perf method에 대해 doc을 읽었습니다.http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html

#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <asm-generic/unistd.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#include "perf_event.h"

#define MAX_COUNTERS        256


static int fd[MAX_COUNTERS];
static unsigned int counter;
static unsigned int nr_cpus =  0; // amount of cpus

//open counter 
long sys_perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                int cpu, int group_fd, unsigned long flags)
{
    int ret;

    ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
                   group_fd, flags);
    return ret;
}



void run_perf_stat()
{

    long long eventContents=0;
    for (counter = 0; counter < nr_cpus; counter++){
        if(fd[counter]!=-1){
            read(fd[counter],&eventContents,sizeof(long long));
            printf("Cache miss in cpu%d:%lld\n",counter+1,eventContents);
        }
        else{
            fprintf(stderr, "Fail to read counter %d\n", counter);
        }
    }
        
        
}




int main(int argc, const char **argv){

    DIR *dir;  //access to dir
    struct dirent *drp;
    int run_count, p, pid;
    struct timespec tim, tim2;
    tim.tv_sec = 1; tim.tv_nsec = 0;
    

    
    nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);// the number of CPU

    printf("Get the number of CPU:%d\n",nr_cpus);


    //create counters for each CPU (system-wide)
    struct perf_event_attr attr; //cache miss
    memset(&attr, 0, sizeof(struct perf_event_attr));
    attr.type = PERF_TYPE_HARDWARE;
    attr.config = PERF_COUNT_HW_CACHE_MISSES;
    attr.size = sizeof(struct perf_event_attr);
    attr.disabled = 0;
        attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |  
                    PERF_FORMAT_TOTAL_TIME_RUNNING;  



    unsigned int cpu = 0;
    for(cpu = 0; cpu < nr_cpus; cpu++)
    fd[cpu] = sys_perf_event_open(&attr, -1, cpu, -1, 0);

    printf("Create counters for each CPU finished!\n");

    //get perf report
    while (1) {
        nanosleep(&tim , &tim2);
        printf("run_perf_stat()!\n");
        run_perf_stat();
    }



    return 1;
}

그리고 나는 또한 주어진 예제를 실행합니다 http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html

그러나 불행히도 결과는 항상 0이기도합니다.

다음은 printf (3) 호출의 총 지시 수를 측정하는 짧은 예입니다.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>

long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
               int cpu, int group_fd, unsigned long flags)
{
   int ret;

   ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
                  group_fd, flags);
   return ret;
}

int
main(int argc, char **argv)
{
   struct perf_event_attr pe;
   long long count;
   int fd;

   memset(&pe, 0, sizeof(struct perf_event_attr));
   pe.type = PERF_TYPE_HARDWARE;
   pe.size = sizeof(struct perf_event_attr);
   pe.config = PERF_COUNT_HW_INSTRUCTIONS;
   pe.disabled = 1;
   pe.exclude_kernel = 1;
   pe.exclude_hv = 1;

   fd = perf_event_open(&pe, 0, -1, -1, 0);
   if (fd == -1) {
      fprintf(stderr, "Error opening leader %llx\n", pe.config);
      exit(EXIT_FAILURE);
   }

   ioctl(fd, PERF_EVENT_IOC_RESET, 0);
   ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

   printf("Measuring instruction count for this printf\n");

   ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
   read(fd, &count, sizeof(long long));

   printf("Used %lld instructions\n", count);

   close(fd);
}
도움이 되었습니까?

해결책

방금 코드를 시도하고 다음 줄 (라인 75,76)을 제거하면 코드가 작동합니다.

attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
                   PERF_FORMAT_TOTAL_TIME_RUNNING;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top