Я пытаюсь «примерно» рассчитать время переключения контекста потока в системе Linux. Я написал программу, которая использует каналы и многопоточность для достижения этой цели. При запуске программы расчетное время явно неверно (см. вывод ниже). Я не уверен, связано ли это с тем, что я использую неправильный clock_id для этой процедуры или, возможно, с моей реализацией.
Я реализовал sched_setaffinity(), чтобы программа работала только на ядре 0. Я пытался оставить как можно больше пуха в коде, чтобы измерять только время переключения контекста, поэтому процесс протектора записывает только один символ в канал, а родитель читает 0 байт.
У меня есть родительский поток, который создает один дочерний поток с односторонним каналом между ними для передачи данных, дочерний поток выполняет простую функцию для записи в канал.
void* thread_1_function()
{
write(fd2[1],"",sizeof("");
}
в то время как родительский поток создает дочерний поток, запускает счетчик времени, а затем вызывает чтение в канале, в который пишет дочерний поток.
int main(int argc, char argv[])
{
//time struct declaration
struct timespec start,end;
//sets program to only use core 0
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
CPU_SET(0,&cpu_set);
if((sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) < 1))
{
int nproc = sysconf(_SC_NPROCESSORS_ONLN);
int k;
printf("Processor used: ");
for(k = 0; k < nproc; ++k)
{
printf("%d ", CPU_ISSET(k, &cpu_set));
}
printf("\n");
if(pipe(fd1) == -1)
{
printf("fd1 pipe error");
return 1;
}
//fail on file descriptor 2 fail
if(pipe(fd2) == -1)
{
printf("fd2 pipe error");
return 1;
}
pthread_t thread_1;
pthread_create(&thread_1, NULL, &thread_1_function, NULL);
pthread_join(thread_1,NULL);
int i;
uint64_t sum = 0;
for(i = 0; i < iterations; ++i)
{
//initalize clock start
clock_gettime(CLOCK_MONOTONIC, &start);
//wait for child thread to write to pipe
read(fd2[0],input,0);
//record clock end
clock_gettime(CLOCK_MONOTONIC, &end);
write(fd1[1],"",sizeof(""));
uint64_t diff;
diff = billion * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
diff = diff;
sum += diff;
}
Результаты, которые я получаю при запуске, обычно выглядят следующим образом:
3000
3000
4000
2000
12000
3000
5000
и т. д., когда я проверяю время, возвращенное в структуры start и end timespec, я вижу, что tv_nsec также кажется «округленным» числом:
start.tv_nsec: 714885000, end.tv_nsec: 714888000
Будет ли это вызвано тем, что clock_monotonic недостаточно точен для того, что я пытаюсь измерить, или какой-то другой проблемой, которую я упускаю из виду?
x86_64
)? В противном случае это повлияет наrvalue
расчетаdiff
. Каков точный тип/определениеbillion
? Это [надеюсь] тожеuint64_t
? - person Craig Estey   schedule 30.01.2019clock_getres
, чтобы убедиться, чтоclock_gettime
использует наносекундную точность. (например) linux будет использовать его, как и большинство других ОС POSIX (например, *BSD, MacOSX), но, поскольку у вас возникают проблемы ...CLOCK_MONOTONIC
[если поддерживается, что во многих местах] похоже наCLOCK_REALTIME
, за исключением того, что он никогда не идет назад во времени. Вы можете попробовать это с обоими вариантами, чтобы увидеть. - person Craig Estey   schedule 31.01.2019