Я выполняю некоторые симуляции Монте-Карло со следующим кодом.
#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 ГГц , технические характеристики которых приведены ниже
У меня есть большая находка!После замены 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