Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
898
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
951
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
941
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1725
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4398
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Гарантируется ли разрешение gettimeofday() в микросекундах?
Я портирую игру, которая изначально была написана для Win32 API, на Linux (ну, портирую порт OS X порта Win32 на Linux).
Я реализовал QueryPerformanceCounter , дав uSeconds с момента запуска процесса:
BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount)
{
gettimeofday(¤tTimeVal, NULL);
performanceCount->QuadPart = (currentTimeVal.tv_sec - startTimeVal.tv_sec);
performanceCount->QuadPart *= (1000 * 1000);
performanceCount->QuadPart += (currentTimeVal.tv_usec - startTimeVal.tv_usec);
return true;
}
Это, в сочетании с QueryPerformanceFrequency() , дающим постоянную 1000000 в качестве частоты , хорошо работает на моей машине, давая мне 64-битную переменную, которая содержит uSeconds с момента запуска программы.
Так это портативное устройство? Я не хочу обнаружить, что он работает по-другому, если kernel был скомпилирован определенным образом или что-то подобное. Однако меня вполне устраивает, что он не переносится на что-то другое, кроме Linux.
Может быть. Но у тебя есть и более серьезные проблемы. gettimeofday() может привести к неправильным таймингам, если в вашей системе есть процессы, которые изменяют таймер (т. е. ntpd). На "normal" linux, однако, я полагаю, что разрешение gettimeofday() равно 10us. Он может прыгать вперед и назад и время, следовательно, на основе процессов, запущенных в вашей системе. Это эффективно делает ответ на ваш вопрос нет.
Вы должны посмотреть в clock_gettime(CLOCK_MONOTONIC) для временных интервалов. Он страдает от нескольких меньших проблем из-за таких вещей, как многоядерные системы и внешние настройки часов.
Кроме того, посмотрите на функцию clock_getres() .
Высокое разрешение, низкие накладные расходы времени для процессоров Intel
Если вы работаете на оборудовании Intel, вот как читать счетчик команд CPU в режиме реального времени. Он сообщит вам количество циклов CPU, выполненных с момента загрузки процессора. Это, вероятно, самый мелкозернистый счетчик, который вы можете получить для измерения производительности.
Обратите внимание, что это число циклов CPU. На linux вы можете получить скорость CPU от /proc/cpuinfo и разделить, чтобы получить количество секунд. Преобразование этого в двойник довольно удобно.
Когда я запускаю это на своей коробке, я получаю
11867927879484732
11867927879692217
it took this long to call printf: 207485
Вот руководство разработчика Intel , которое дает массу подробностей.
#include <stdio.h>
#include <stdint.h>
inline uint64_t rdtsc() {
uint32_t lo, hi;
__asm__ __volatile__ (
"xorl %%eax, %%eax\n"
"cpuid\n"
"rdtsc\n"
: "=a" (lo), "=d" (hi)
:
: "%ebx", "%ecx");
return (uint64_t)hi << 32 | lo;
}
main()
{
unsigned long long x;
unsigned long long y;
x = rdtsc();
printf("%lld\n",x);
y = rdtsc();
printf("%lld\n",y);
printf("it took this long to call printf: %lld\n",y-x);
}
@Bernard:
Должен признаться, что большая часть вашего примера прошла мимо моей головы. Он действительно компилируется и, кажется, работает. Это безопасно для систем SMP или SpeedStep?
Это хороший вопрос... Я думаю, что код в порядке. С практической точки зрения, мы используем его в моей компании каждый день, и мы работаем на довольно широком спектре коробок, все от 2-8 ядер. Конечно, YMMV и т.д., Но это вроде бы надежный и малозатратный вариант (потому что он не делает переключение контекста в системное пространство) метод о сроках.
Вообще, как это работает:
- объявите блок кода ассемблером (и изменчивым, так что оптимизатор оставит его в покое).
- выполните инструкцию CPUID. В дополнение к получению некоторой информации CPU (с которым мы ничего не делаем) он синхронизирует буфер выполнения CPU так что на тайминги не влияет выполнение out-of-order.
- выполните выполнение rdtsc (read timestamp). Это позволяет получить число машинные циклы выполняются с момента сброса процессора. Это 64-битная версия значение, так что с текущими скоростями CPU он будет оборачиваться каждые 194 года или около того. Интересно, что в оригинальной ссылке Pentium они отмечают, что он обертывает каждый 5800 лет или около того.
- последние две строки хранят значения из регистров в переменные hi и lo, и поместите их в 64-битное возвращаемое значение.
Конкретные замечания:
out-of-order выполнение может привести к неверным результатам, поэтому мы выполняем "cpuid" инструкция, которая в дополнение к предоставлению вам некоторой информации о cpu также синхронизирует выполнение любой инструкции out-of-order.
Большинство OS синхронизируют счетчики на CPUs, когда они начинаются, так что ответ хорош уже через пару нано-секунд.
Спящий комментарий, вероятно, верен, но на практике вы вероятно, им наплевать на тайминги, пересекающие границы гибернации.
что касается speedstep: новые Intel CPUs компенсируют скорость изменяет и возвращает скорректированный счетчик. Я быстро осмотрел все вокруг некоторые из ящиков в нашей сети и нашли только один ящик, который у меня его не было: Pentium 3, работающий на каком-то старом сервере баз данных. (это коробки linux, поэтому я проверил с помощью: grep constant_tsc /proc/cpuinfo)
Я не уверен насчет AMD CPUs, мы в первую очередь магазин Intel, хотя я знаю, что некоторые из наших низкоуровневых системных гуру сделали AMD оценка.
Надеюсь, это удовлетворит ваше любопытство, это интересно и (IMHO) малоизученная область программирования. Ты же знаешь когда Джефф и Джоэл были вместе говоря о том, должен ли программист знать C? Я был крикнув им: "Эй, забудьте эту высокоуровневую штуку C... ассемблер это то, что вы должны узнать, если хотите знать, что такое компьютер делать!"
Wine фактически использует gettimeofday() для реализации QueryPerformanceCounter(), и известно, что многие игры Windows работают на Linux и Mac.
Начинается http://source.winehq.org/source/dlls/kernel32/cpu.c#L312
приводит к http://source.winehq.org/source/dlls/ntdll/time.c#L448
Поэтому он явно говорит о микросекундах,но говорит, что разрешение системных часов не определено. Я полагаю, что разрешение в этом контексте означает, как наименьшее количество его когда-либо будет увеличено?
Поэтому он явно говорит о микросекундах,но говорит, что разрешение системных часов не определено. Я полагаю, что разрешение в этом контексте означает, как наименьшее количество его когда-либо будет увеличено?
Структура данных определяется как имеющая микросекунды в качестве единицы измерения, но это не означает, что часы или операционная система действительно способны измерять это точно.
Как и другие люди предположили, gettimeofday() плохо, потому что установка времени может вызвать перекос часов и сбить ваш расчет. clock_gettime(CLOCK_MONOTONIC) - это то, что вам нужно, а clock_getres() покажет вам точность ваших часов.
Фактическое разрешение gettimeofday() зависит от аппаратной архитектуры. Процессоры Intel, а также машины SPARC предлагают таймеры высокого разрешения, которые измеряют микросекунды. Другие аппаратные архитектуры опираются на таймер системы, который обычно устанавливается на 100 Гц. В таких случаях временное разрешение будет менее точным.
Фактическое разрешение gettimeofday() зависит от аппаратной архитектуры. Процессоры Intel, а также машины SPARC предлагают таймеры высокого разрешения, которые измеряют микросекунды. Другие аппаратные архитектуры опираются на таймер системы, который обычно устанавливается на 100 Гц. В таких случаях временное разрешение будет менее точным.
Я получил этот ответ от измерения времени с высоким разрешением и таймеров, Часть I
В этом ответе упоминаются проблемы с настройкой часов. Как ваши проблемы с гарантированием тиковых единиц, так и проблемы с корректировкой времени решаются в C++11 с помощью библиотеки <chrono> .
Часы std::chrono::steady_clock гарантированно не будут отрегулированы, и, кроме того, они будут двигаться с постоянной скоростью относительно реального времени, поэтому такие технологии, как SpeedStep, не должны влиять на него.
Вы можете получить типовые единицы измерения, преобразовав их в одну из специализаций std::chrono::duration , например std::chrono::microseconds . С этим типом нет никакой двусмысленности относительно единиц измерения, используемых значением тика. Однако имейте в виду, что часы не обязательно имеют такое разрешение. Вы можете преобразовать длительность в аттосекунды, не имея на самом деле таких точных часов.
Чтение RDTSC не является надежным в системах SMP, так как каждый CPU поддерживает свой собственный счетчик и каждый счетчик не гарантируется синхронизацией по отношению к другому CPU.
Я мог бы предложить попробовать clock_gettime(CLOCK_REALTIME) . Руководство posix указывает, что это должно быть реализовано на всех совместимых системах. Он может обеспечить отсчет наносекунд, но вы, вероятно, захотите проверить clock_getres(CLOCK_REALTIME) в своей системе, чтобы увидеть, каково фактическое разрешение.