Программа работает в 10 раз медленнее на 2,5 ГГц Xeon, чем на 2,3 ГГц Core i5 - PullRequest
2 голосов
/ 20 марта 2019

Я выполняю некоторые симуляции Монте-Карло со следующим кодом.

#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>

#define L 20
#define N 200000


int main() {
    struct timespec ts_start, ts_end;
    clock_t clk_start, clk_end;
    struct rusage usage;
    struct timeval tv_ustart, tv_uend;
    struct timeval tv_sstart, tv_send;

    clock_gettime(CLOCK_MONOTONIC, &ts_start);
    clk_start = clock();
    getrusage(RUSAGE_SELF, &usage);
    tv_ustart = usage.ru_utime;
    tv_sstart = usage.ru_stime;

    /* 
     * the runtime of one simulation may vary a lot, so let's repeat it many times.
     */
    for (int iteration = 0; iteration < N; iteration += 1) {
        int node_num_by_depth[L + 1] = {1};

        for (int level = 0; level < L; level += 1) {
            for (int depth = level; depth != -1; depth -= 1) {
                int parent_num = node_num_by_depth[depth];
                node_num_by_depth[depth] = 0;
                for (int parent = 0; parent < parent_num; parent += 1) {
                    int child_num = 1 + arc4random() % 2;
                    int child_depth = depth + (child_num > 1);
                    node_num_by_depth[child_depth] += child_num;
                }
            }
        }
    }

    clock_gettime(CLOCK_MONOTONIC, &ts_end);
    clk_end = clock();
    getrusage(RUSAGE_SELF, &usage);
    tv_uend = usage.ru_utime;
    tv_send = usage.ru_utime;


    double elapsed = (double) (ts_end.tv_sec - ts_start.tv_sec)
                     + (double) (ts_end.tv_nsec - ts_start.tv_nsec) / 1E9;
    printf("Wall clock time elapsed: %g\n", elapsed);

    double cpu_time_used = ((double) (clk_end - clk_start)) / CLOCKS_PER_SEC;
    printf("CPU time elapsed: %g\n", cpu_time_used);

    printf("User CPU time elapsed: %lu.%06u\n",
           tv_uend.tv_sec - tv_ustart.tv_sec,
           tv_uend.tv_usec - tv_ustart.tv_usec);

    printf("System CPU time elapsed: %lu.%06u\n",
           tv_send.tv_sec - tv_sstart.tv_sec,
           tv_send.tv_usec - tv_sstart.tv_usec);
}

При работе на моем MacBook Pro с 2.3GHz dual-core Intel Core i5, Turbo Boost up to 3.6GHz, with 64MB of eDRAM вывод составляет

Wall clock time elapsed: 32.408
CPU time elapsed: 32.3566
User CPU time elapsed: 32.319151
System CPU time elapsed: 32.319114

При работе на моем сервере FreeBSD с CPU: Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz (2499.96-MHz K8-class CPU) он дает мне

Wall clock time elapsed: 396.563
CPU time elapsed: 396.414
User CPU time elapsed: 158.377633
System CPU time elapsed: 158.376629

В обоих случаях я использовал инструкцию по компиляции clang main.c -Ofast -march=native -o main.

Первоначально серверработал Ubuntu 18.04, но я переключился на FreeBSD после того, как понял, что моя программа работает смехотворно медленно.Однако даже во FreeBSD (где arc4random предоставляется изначально), он все еще значительно менее эффективен.Теперь, если нет очень веских причин, я не хочу снова переключаться на новую ОС.

Я профилировал программу с помощью gprof, и вы можете найти результат здесь .Мы видим, что arc4random занимает довольно много времени (30,8%), но это не может быть единственной причиной десятикратного снижения производительности.


Я добавил некоторые другие меры временикак указано в комментариях.Вы можете видеть, что существует огромный разрыв между временем настенных часов и временем процессора.Могу ли я сузить это?В любом случае, меня волнует, сколько времени занимает выполнение моей программы, а не сколько циклов ЦП.


Вот некоторая расширенная информация о моем MacBook Pro

Hardware Overview:

  Model Name: MacBook Pro
  Model Identifier: MacBookPro14,1
  Processor Name: Intel Core i5
  Processor Speed: 2.3 GHz
  Number of Processors: 1
  Total Number of Cores: 2
  L2 Cache (per Core): 256 KB
  L3 Cache: 4 MB
  Memory: 8 GB
  Boot ROM Version: 184.0.0.0.0
  SMC Version (system): 2.43f6
  Serial Number (system): XXXXXXXXXXXX
  Hardware UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

Мой сервер оснащен двенадцатью процессорами Intel Skylake Xeon Platinum 8163 2,5 ГГц , технические характеристики которых приведены ниже

enter image description here


У меня есть большая находка!После замены arc4random на random на сервере наблюдается огромный прирост производительности.

  • MacBook Pro с random

    Wall clock time elapsed: 5.61316
    CPU time elapsed: 5.40623
    User CPU time elapsed: 5.361931
    System CPU time elapsed: 5.359096
    
  • Сервер с random

    Wall clock time elapsed: 6.69183
    CPU time elapsed: 6.6875
    User CPU time elapsed: 6.690042
    System CPU time elapsed: 6.689085
    
...