значения счетчиков производительности возвращают ноль, используя приложение papi

Я пытаюсь прочитать счетчик производительности оборудования с помощью PAPI и написал следующий код:

#include <stdio.h>
#include <stdlib.h>
#include "papi.h" /* This needs to be included every time you use PAPI */
#include <unistd.h>

#define NUM_EVENTS 2
#define ERROR_RETURN(retval) { fprintf(stderr, "Error %d %s:line %d: \n", retval,__FILE__,__LINE__);  exit(retval); }

int main(int argc, char *argv[])
{

   if(argc<=1) {
        printf("Pid is not provided, I will die now :( ...");
        exit(1);
     }  //otherwise continue on our merry way....

   int EventSet = PAPI_NULL;
   int tmp, i;
   /*must be initialized to PAPI_NULL before calling PAPI_create_event*/

   long long values[NUM_EVENTS];
   /*This is where we store the values we read from the eventset */

   /* We use number to keep track of the number of events in the EventSet */
   int retval, number;

   char errstring[PAPI_MAX_STR_LEN];
   pid_t pid = atoi(argv[1]);

   unsigned int l2miss = 0x0;
   unsigned int data_all_from_l2 = 0x0;
   /*************************************************************************** 
   *  This part initializes the library and compares the version number of the*
   * header file, to the version of the library, if these don't match then it *
   * is likely that PAPI won't work correctly.If there is an error, retval    *
   * keeps track of the version number.                                       *
   ***************************************************************************/


   if((retval = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT )
      ERROR_RETURN(retval);


   /* Creating the eventset */
   if ( (retval = PAPI_create_eventset(&EventSet)) != PAPI_OK)
      ERROR_RETURN(retval);


   /* Add Native event to the EventSet */
   // if ( (retval = PAPI_event_name_to_code("PM_DATA_FROM_L2MISS",&l2miss)) != PAPI_OK)
    if ( (retval = PAPI_event_name_to_code("PM_L3_CO_MEM",&l2miss)) != PAPI_OK)
      ERROR_RETURN(retval);

    if ( (retval = PAPI_add_event(EventSet, l2miss)) != PAPI_OK)
      ERROR_RETURN(retval);

   /* Add Native event to the EventSet */
    if ( (retval = PAPI_event_name_to_code("PM_DATA_ALL_FROM_L2",&data_all_from_l2)) != PAPI_OK)
      ERROR_RETURN(retval);

    if ( (retval = PAPI_add_event(EventSet, data_all_from_l2)) != PAPI_OK)
      ERROR_RETURN(retval);


   /* get the number of events in the event set */
   number = 0;
   if ( (retval = PAPI_list_events(EventSet, NULL, &number)) != PAPI_OK)
      ERROR_RETURN(retval);

   printf("There are %d events in the event set\n", number);


  retval = PAPI_attach( EventSet, ( unsigned long ) pid );
        if ( retval != PAPI_OK )
        ERROR_RETURN(retval);


   /* Start counting */

   if ( (retval = PAPI_start(EventSet)) != PAPI_OK)
      ERROR_RETURN(retval);

       while(kill(pid,0)==0)
        {
                if ( (retval=PAPI_read(EventSet, values)) != PAPI_OK)
                      ERROR_RETURN(retval);

           printf("The L2 Miss are %lld \n",values[0]);
           printf("The data_all_from_l2 are %lld \n",values[1]);
                sleep(1);
        }//while   

   /* Stop counting and store the values into the array */
   if ( (retval = PAPI_stop(EventSet, values)) != PAPI_OK)
      ERROR_RETURN(retval);

   printf("Total L2 Miss are %lld \n",values[0]);
   printf("Total data_all_from_l2 are %lld \n",values[1]);


   /* free the resources used by PAPI */
   PAPI_shutdown();

   exit(0);
}

Я компилирую его с помощью следующей команды:

gcc -I/apps/PAPI/5.5.0/GCC/5.4.0/CUDA/8.0/include -O0 pid_ex.c  -L/apps/PAPI/5.5.0/GCC/5.4.0/CUDA/8.0/lib -lpapi -o pid_ex

и я запускаю это так:

./pid_ex 7865

где 7865 — идентификатор запущенного процесса.

Проблема в том, что он показывает нулевые значения вместо отображения значений счетчика.

Может ли кто-нибудь дать мне знать, почему он ведет себя так? Почему он не получает значения?


person Shuja    schedule 25.10.2016    source источник
comment
Показывает ли он нули в каждом вызове printf? Даже те, что внутри цикла while?   -  person fedepad    schedule 16.12.2016


Ответы (1)


Пара вещей, я скомпилировал и попытался запустить ваш код. Я скомпилировал с -Wall, и вам, вероятно, следует изменить:

unsigned int l2miss = 0x0;
unsigned int data_all_from_l2 = 0x0;

в

int l2miss = PAPI_NULL;
int data_all_from_l2 = PAPI_NULL;

так вы избавитесь от пары предупреждений.

Затем я попытался просто запустить ваш код, и я получил эту ошибку:

Ошибка -7 papi-test.c:line...

который представляет собой код ошибки PAPI, когда данное событие недоступно для вашего компьютера, выдаваемое следующими вызовами функций:

if ( (retval = PAPI_event_name_to_code("PM_DATA_FROM_L2MISS",&l2miss)) != PAPI_OK)

и

if ( (retval = PAPI_event_name_to_code("PM_DATA_ALL_FROM_L2",&data_all_from_l2)) != PAPI_OK)

Учитывая это, я проверил, какие события доступны для моей машины, и получил следующее:

$ papi_avail

и ваши события были недоступны для меня. Итак, чтобы проверить ваш код, я изменил записываемые события и установил для них:

PAPI_L1_DCM

PAPI_L2_DCM

которые представляют соответственно промахи кэша данных L1 и L2. И затем я запускаю вашу программу против четырех программ: firefox, java, программа, которая просто спит, и корица (Linux Mint).

Кажется, что события записываются, как вы можете видеть: Firefox:

./папи-тест 3922

В наборе событий 2 события

Мисс L2 - 0

data_all_from_l2 равны 0

Мисс L2 - 130534

data_all_from_l2: 104151

Мисс L2: 266181

data_all_from_l2: 212618
...

Для программ, которые просто спят, я получаю:

./папи-тест 7870

В наборе событий 2 события

Мисс L2 - 0

data_all_from_l2 равны 0

Мисс L2 - 0

data_all_from_l2 равны 0

Мисс L2 - 0

data_all_from_l2: 0
...

Пожалуйста, не обращайте внимания на строку, напечатанную перед номером, так как я сохранил вашу строку, когда вы печатаете события, хотя зарегистрированные события разные, и я только что упомянул выше, какие из них я использовал, чтобы иметь возможность запускать их на своем компьютере. Таким образом, кажется, что я не просто постоянно получаю нули, но и завишу от программы, за которой наблюдаю.
Используемая версия PAPI — 5.4.3.
Кроме того, хотя у меня нет предложений на момент, позаботьтесь об условии в цикле while, который вы проверяете, поскольку может случиться так, что, пока вы спите внутри цикла, программа, связанная с PID, может завершиться, а ее PID повторно используется и назначается другому процессу, и вы все равно будете удовлетворять условию, но в В этом случае вы можете искать не ту программу, о которой изначально думали.
Также было обсуждение
https://lists.eecs.utk.edu/pipermail/ptools-perfapi/2016-октябрь/004060.html?cm_mc_uid=+57211302537614804702521&cm_mc_sid_50200000=1482029904 используя некоторые события, подобные вашим.
Кроме того, используемые вами события определены для компьютеров power8. (https://lkml.org/lkml/2015/5/27/858), поэтому вы, вероятно, используете машину power8.

person fedepad    schedule 16.12.2016