J'ai lu la valeur du compteur avec perf sur Linux, la valeur de celle-ci est toujours 0

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

  •  25-07-2022
  •  | 
  •  

Question

Je gère le programme sur Ubuntu 12.04, la valeur des compteurs est Awalys 0. Il semble que mes compteurs ne fonctionnent pas pour moi.

Lorsque j'exécute le programme, l'ouput est:


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

Je ne peux pas donner un sens à l'image des valeurs.

J'ai lu le doc sur la méthode perf à: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;
}

Et je gère également l'exemple donné à http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html

Mais, malheureusement, le résultat est toujours 0 aussi, là-bas vient l'exemple dans la page d'homme.

Ce qui suit est un court exemple qui mesure le nombre total d'instructions d'un appel à 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);
}
Était-ce utile?

La solution

Je viens d'essayer votre code et de supprimer les lignes suivantes (ligne n ° 75,76) fait fonctionner le code pour moi.

attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
                   PERF_FORMAT_TOTAL_TIME_RUNNING;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top