я использую _rdtsc()
в компиляторах Intel, чтобы получить счетчик меток времени. я использую _rdtsc()
в сочетании с mkl_get_clocks_frequency()
, чтобы преобразовать показания счетчика меток времени в секунды. Оба они специфичны для компиляторов Intel.
Хотя у меня есть эквивалент _rdtsc()
на компиляторах GNU, использующих встроенную сборку, у меня нет того же для mkl_get_clocks_frequency()
,
Как я могу оценить тактовую частоту процессора в портативном режиме?
Я дам вам не ответ. Извините, но, насколько я знаю, нет хорошего ответа на это. RDTSC
будет работать только на определенных процессорах в очень специфических условиях, возвращая значения, интерпретация которых находится где-то между жестким и невозможным без помощи операционной системы, поэтому я подозреваю, что никто не удосужился реализовать такую поддержку в переносимых компиляторах / библиотеках (все остальные ожидают, что Компилятор Intel).
Вот длинная история:
RDTSC
инструкция имеет долгую историю семантических изменений, которые очень трудно отслеживать в приложении. В старых процессорах Intel и AMD TSC считал только внутренние циклы, что означало, что при переменной частоте (режимы энергосбережения и т. Д.) Частота могла изменяться без какого-либо уведомления приложения. Частота могла изменяться несколько раз между двумя временными метками, и вы не могли знать, что это произошло.
Некоторые версии CPU или BIOS могут приостанавливать TSC в режиме управления системой, а другие — нет. Первое поведение означало, что TSC был бесполезен для настенного времени, другое означало, что TSC бесполезен для бенчмаркинга. В прошлый раз, когда я смотрел на это, не было никакого способа обнаружить это, кроме как сравнивать с другими часами и искать большие прыжки.
Некоторые процессоры не поддерживали синхронизацию TSC и / или его частоты между несколькими процессорами в системе. Это означает, что если операционная система перемещает ваш процесс между процессорами, то значение TSC, которое вы читаете, в лучшем случае совершенно бесполезно, а в худшем случае слегка вводит в заблуждение.
Недавняя тенденция и обещание стабильности заключались в том, чтобы иметь синхронизированный таймер и синхронизированную статическую частоту (чего вы не можете достичь, потому что часы чувствительны к температуре, но это другая история). Мы можем наконец-то стабильно использовать RDTSC без проблем.
Но затем Intel бросил нам еще один кривая, внезапно решив, что RDTSC
больше не является инструкцией по сериализации (скорее всего, это не осознанное решение, вероятно, это просто ошибка, с которой Intel сходит с рук, говоря, что «она никогда не была документирована для сериализации»). Это означает, что если вы дважды прочитаете таймер в своем коде, второе значение может быть ниже первого значения. Или, что еще хуже, большая часть кода, который вы тестируете, на самом деле не была запущена. Новый RDTSCP
Инструкция «решает» эту проблему, но вам нужно выяснить, какие процессоры на самом деле ее реализуют, а какие достаточно надежные RDTSC
что вы можете использовать, и какие из них вы просто должны отказаться и использовать лучший источник времени.
Чтобы добавить к этому, вы не знаете, работает ли ваш код между двумя вызовами RDTSC
или если вы переключили контекст. Поэтому я бы предложил придерживаться возможностей синхронизации, которые предоставляет ваша операционная система, и измерить время выполнения вашего процесса. Эти средства синхронизации работают медленнее, но операционная система, скорее всего, решила все эти проблемы гораздо лучше, чем вы когда-либо сможете понять. В качестве бонуса, если вы используете NTP или какой-либо другой механизм синхронизации времени, вы также получите тактовые частоты намного ближе к реальным секундам, поскольку они также отслеживают долгосрочный и краткосрочный сдвиг частоты, который вы, как приложение, не можете знать.
Вы не можете сделать это переносимо, и если вы сделали это, это бессмысленно, как объяснено в Арт ответ.
На Linux конкретно, вы можете разобрать /proc/cpuinfo
чтобы получить некоторую информацию (которая может быть неправильной, к тому времени, когда вы ее анализируете), о некоторых частотах процессора. Но это все еще бессмысленно.
В Linux вы должны прочитать Время (7) и практически использовать clock_gettime (2) который работает быстро, благодаря vdso (7) технология.
С C ++ 11-совместимым компилятором & реализация (т.е. libstdc++
), вы могли бы использовать <chrono>
ПОКО Фреймворковая библиотека (охватывающая несколько ОС) имеет некоторую поддержку таймера.