Основная модификация, которую я делаю для схемы синхронизации, которую вы намечаете, заключается в обеспечении того, чтобы один и тот же код времени использовался для обеих функций - при условии, что у них есть идентичный интерфейс, передавая указатель функции на скелетный код.
В качестве примера у меня есть код, который выполняет некоторые функции, которые проверяют, является ли заданное число простым. Функция управления:
static void test_primality_tester(const char *tag, int seed, int (*prime)(unsigned), int count)
{
srand(seed);
Clock clk;
int nprimes = 0;
clk_init(&clk);
clk_start(&clk);
for (int i = 0; i < count; i++)
{
if (prime(rand()))
nprimes++;
}
clk_stop(&clk);
char buffer[32];
printf("%9s: %d primes found (out of %d) in %s s\n", tag, nprimes,
count, clk_elapsed_us(&clk, buffer, sizeof(buffer)));
}
Я хорошо осведомлен о srand()
— why call it once?, но смысл использовать srand()
раз каждый раз, когда эта функция вызывается, чтобы гарантировать, что тесты обработать ту же последовательность случайных чисел. На macOS, RAND_MAX
- 0x7FFFFFFF
.
Тип Clock
содержит аналоги для двух конструкций struct timespec
, для начала и остановки. Функция clk_init()
инициализирует структуру; clk_start()
записывает время начала в структуре; clk_stop()
записывает время остановки в структуре; и clk_elapsed_us()
вычисляет истекшее время между временем начала и остановки в микросекундах. Пакет написан, чтобы предоставить мне кросс-платформенную переносимость (за счет некоторых головных болей при определении того, какая из лучших подсекундных подпрограмм, доступных во время компиляции).
Вы можете найти свой код для таймеров на Github в хранилище https://github.com/jleffler/soq, в каталоге src/libsoq
- файлы timer.h
и timer.c
. Код еще не догнал macOS Sierra с clock_gettime()
, хотя его можно было скомпилировать с использованием -DHAVE_CLOCK_GETTIME
в качестве параметра компилятора командной строки.
Этот код вызывается из функции one_test()
:
static void one_test(int seed)
{
printf("Seed; %d\n", seed);
enum { COUNT = 10000000 };
test_primality_tester("IsPrime1", seed, IsPrime1, COUNT);
test_primality_tester("IsPrime2", seed, IsPrime2, COUNT);
test_primality_tester("IsPrime3", seed, IsPrime3, COUNT);
test_primality_tester("isprime1", seed, isprime1, COUNT);
test_primality_tester("isprime2", seed, isprime2, COUNT);
test_primality_tester("isprime3", seed, isprime3, COUNT);
}
И основной программе может принять одну или серию семян, или использует текущее время в качестве затравки:
int main(int argc, char **argv)
{
if (argc > 1)
{
for (int i = 1; i < argc; i++)
one_test(atoi(argv[i]));
}
else
one_test(time(0));
return(0);
}
Если вы «Работая с macOS Sierra (10.12) или более поздней версией, в конечном итоге поддерживается« clock_gettime() », предоставляемая системой, хотя реальное разрешение - это только микросекунды, а не наносекунды. (То есть компонент 'tv_nsec' ответа от' clock_gettime() 'всегда заканчивается тремя нулями.) Вопрос, на который вы ссылаетесь, предваряет Сьерра более чем на четыре года. –
Ну, я работаю с 10.11, а вызовы функций заголовка машины из задания все еще работают. Но это хорошо знать. – TSIguy