Pregunta

Ejecuto el programa en Ubuntu 12.04, el valor de los contadores es Awalys 0. Parece que mis contadores no funcionaron para mí.

Cuando ejecuto el programa, la salida es:


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

No puedo dar sentido a los valores.

He leído el documento sobre el método PERF en: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;
}

Y también ejecuto el ejemplo dado en http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html

Pero, desafortunadamente, el resultado siempre es 0, también viene el ejemplo en la página de hombre.

El siguiente es un breve ejemplo que mide el recuento total de instrucciones de una llamada a 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);
}
¿Fue útil?

Solución

Acabo de probar su código y eliminar las siguientes líneas (línea no 75,76) hace que el código funcione para mí.

attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
                   PERF_FORMAT_TOTAL_TIME_RUNNING;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top