Эффективное влияние частоты дискретизации на производительность - более высокая частота дискретизации стоит * меньше * накладных расходов на NXP S32? - PullRequest
2 голосов
/ 07 апреля 2020

Я использую perf в режиме выборки для сбора статистики производительности программ, работающих на многоядерной платформе с платформы NXP S32 Linux 4.19.

Например, конфигурация

Core 0 - App0 , Core 1 - App1, Core 2 - App2

Без выборки, то есть на уровне программы, App0 занимает 6,9 секунды.

При выборке с 1 миллионом циклов App0 занимает 6,3 сек c

При выборке с циклом 2 миллиона App0 занимает 6,4 с c

При выборке с циклом 5 миллионов App0 занимает 6,5 с c

При выборке с циклом 100 миллионов App0 занимает 6,8 se c.

Как вы можете видеть с более высоким периодом выборки (100 миллионов), App0 занимает больше времени, чтобы завершить выполнение sh.

На самом деле я ожидал обратного, то есть выборки при 1 миллион циклов должен был привести к тому, что программе потребовалось бы больше времени для выполнения из-за большего количества сгенерированных выборок (непроизводительных издержек) по сравнению со 100 миллионами циклов?

Я не могу объяснить это поведение Как вы думаете, что вызывает это?

Любые выводы будут полезны.

PS - На Pi3B поведение такое, как и ожидалось, т.е. выборка с 1 миллионами циклов приводит к более длительному времени выполнения по сравнению с 100 миллионами циклы.


ОБНОВЛЕНИЕ: я не использую perf из командной строки, вместо этого выполняю системный вызов perf, используя perf event со следующими флагами в struct perf_event_attr.

    struct perf_event_attr hw_event;
    pid_t pid = proccess_id;    // measure the current process/thread
    int cpu = -1;   // measure on any cpu
    unsigned long flags = 0;
    int fd_current;


    memset(&hw_event, 0, sizeof(struct perf_event_attr));
    hw_event.type = event_type;
    hw_event.size = sizeof(struct perf_event_attr);
    hw_event.config = event;
    if(group_fd == -1)
    {
        hw_event.sample_period = 2000000;
        hw_event.sample_type = PERF_SAMPLE_READ;
        hw_event.precise_ip = 1;
    }

    hw_event.disabled = 1;          // off by default. specifies whether the counter starts out disabled or enabled.
    hw_event.exclude_kernel = 0;    // excluding events that happen in the kernel-space
    hw_event.exclude_hv = 1;        // excluding events that happen in the hypervisor
    hw_event.pinned = pinned;       // specifies the counter to be on the CPU if at all possible. applies only to hardware counters and only to group leaders.
    hw_event.exclude_user = 0;      //  excludes events that happen in user space
    hw_event.exclude_callchain_kernel  = 0; // Do not include kernel callchains.
    hw_event.exclude_callchain_user = 0;    // Do not include user callchains.
    hw_event.read_format = PERF_FORMAT_GROUP; // Allows all counter values in an event group to be read with one read
    fd_current = syscall(__NR_perf_event_open, &hw_event, pid, cpu, group_fd, flags);
    if (fd_current == -1) {
      printf("Error opening leader %llx\n", hw_event.config);
      exit(EXIT_FAILURE);
    }

   return fd_current; 
...