Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прочитать точный счетчик из пространства пользователя(rdtsc)
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
Kris2007
Нужно поюзать какой-нибудь точный счетчик циклов из-под ОС Linux из пространства пользователя.
Кроме clock_gettime ничего в голову не приходит. Существует ли какой-нибудь счетчик типа rdtsc для x86, который можно использовать из пространства пользователя(для включения которого не нужен kernel mode)?

Olej
Цитата(Kris2007 @ Feb 28 2012, 11:31) *
Нужно поюзать какой-нибудь точный счетчик циклов из-под ОС Linux из пространства пользователя.
Кроме clock_gettime ничего в голову не приходит. Существует ли какой-нибудь счетчик типа rdtsc для x86, который можно использовать из пространства пользователя(для включения которого не нужен kernel mode)?


если это x86, то нет ничего проще wink.gif
Код
unsigned long long rdtsc( void ) {
   unsigned long long int x;
   asm volatile ( "rdtsc" : "=A" (x) );
   return x;
}

более развернуто можете посмотреть примеры в книжке: Инструменты Linux для программистов Windows.
там же есть архивы примеров (http://rus-linux.net/MyLDP/BOOKS/Linux-tools/Texamples.2.46.tgz), где эти вещи обыгрываются (проект time).

если это другая платформа, то там всё зависит от специфики, но по аналогии вы можете сделать такое же.
Kris2007
ОС Андроид, платформа ARM(конкретные процессоры я предполагаю будут разнообразные), суть вопроса именно(!) как сделать по-аналогии для ARM.
Olej
Цитата(Kris2007 @ Feb 28 2012, 11:31) *
(для включения которого не нужен kernel mode)?


это вопрос уже а). архитектуры ARM и на разных семействах ARM могут быть различия, б). вопрос того, что разработчики kernel сочли нужным в архитектурно-зависимой части включить в kernel API ... (посмотрю на досуге).

а если вы знаете что-то подходящее из kernel API под ваши цели - сделайте под него syscall() под ваши цели, который можно подгружать и динамически, чтоб не отходить от типового ядра Linux.

вот я беру на своём Android (кстати, какой вас интересует Android, версия?) делаю:
Код
[olej@notebook platform-tools]$ ./adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
0123456789ABCDEF        device
[olej@notebook platform-tools]$ ./adb -s 0123456789ABCDEF shell
# cd /proc
# cat /proc/kallsyms | grep sys_ | grep T
c00173c8 T proc_sys_init
c002ff88 T sys_call_table
c003060c T sys_oabi_call_table
c0033024 T sys_rt_sigreturn
c00330e0 T sys_sigreturn
c0033180 T sys_sigaction
...

- вот они все kernel API, родёмые, как на ладони...
- adb - это из состава Android SDK, вы уже развернули Android SDK?
Kris2007
Да развернул.
clock_gettime(другого решения пока не нашел( ) насколько я понимаю использует системный вызов sys_timer_gettime.
Но это много дольше, чем просто прочитать регистр таймера в x86(

Olej
Цитата(Kris2007 @ Feb 29 2012, 11:40) *
clock_gettime(другого решения пока не нашел( ) насколько я понимаю использует системный вызов sys_timer_gettime.


Код
[olej@notebook 2012_WORK]$ cat /proc/kallsyms | grep T | grep clock_gettime
c045a5ee T sys_clock_gettime


Цитата(Kris2007 @ Feb 29 2012, 11:40) *
Но это много дольше, чем просто прочитать регистр таймера в x86(

при чём здесь вообще "дольше" или "короче" при таких элементарных операциях?
если вас устраивает разрешение с дискретностью HZ (счётчик ядра jiffies - системное время), то clock_gettime() или что-то подобное из <linux/time.h> - это самое то, что вам и надо... rdtsc и в x86 используется только в крайних случаях, и исключительно когда дискретность измерений должна быть мельче HZ.

Kris2007
Цитата(Olej @ Feb 29 2012, 13:58) *
Код
[olej@notebook 2012_WORK]$ cat /proc/kallsyms | grep T | grep clock_gettime
c045a5ee T sys_clock_gettime



при чём здесь вообще "дольше" или "короче" при таких элементарных операциях?
если вас устраивает разрешение с дискретностью HZ (счётчик ядра jiffies - системное время), то clock_gettime() или что-то подобное из <linux/time.h> - это самое то, что вам и надо... rdtsc и в x86 используется только в крайних случаях, и исключительно когда дискретность измерений должна быть мельче HZ.


Это критичный момент. Код портируется на много платформ x86, mips, porepc, IOS(на ARM) и т п для всех своя реализация на асме. Для IOS через функцию mach_absolute_time(), андроиде подобной увы нет.
Olej
Цитата(Kris2007 @ Feb 29 2012, 17:31) *
Это критичный момент. Код портируется на много платформ x86, mips, porepc, IOS(на ARM) и т п для всех своя реализация на асме. Для IOS через функцию mach_absolute_time(), андроиде подобной увы нет.

подождите! wink.gif - это не критичный момент!

единственный критичный момент: нужна ли вам дискретность времени выше системного таймера? (менее 1/HZ)

если нет, то ответ однозначно один:

- если у вас программа юзерспейс, то независимо отлюбых аппаратных платформ, в POSIX системе Linux должны использоваться только POSIX API вызовы... - clock_gettime() etc.
- и тогда у вас даже мыслей дурных не будет возникать: портируется - не портируется.

P.S. что касается iOS, то это слишком широкое спектр портирования, и тут вам придётся чего-то изобретать, но ... уже на сегодня объём смартфонов под iOS меньше Android (который Linux) скоро в 3 раза и это соотношение только усугубляется.
Kris2007
Нужна.
Цитата(Olej @ Feb 29 2012, 18:52) *
единственный критичный момент: нужна ли вам дискретность времени выше системного таймера? (менее 1/HZ)

xor.kruger
Практически все возможные операции (решения) со временем в GNU/Linux описаны в книге Р.Лав "Linux. System Programming" в главе "Time". Может быть найдете там что нибудь полезное.
Olej
Цитата(Kris2007 @ Mar 1 2012, 10:50) *
Нужна.

посмотрите тогда, для начала, на таймеры ядра высокого разрешения (как их назвали - появились они с ядра 2.6.16).
как это выглядит на ARM я не знаю, вот (возможно) оно и есть, это на моём железном планшете с Android:
Код
[olej@notebook platform-tools]$ ./adb -s 0123456789ABCDEF shell
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
# cat /proc/kallsyms | grep ktime | grep T
c0057d5c T mktime
c006a118 T ktime_add_ns
c006a1f0 T ktime_sub_ns
c006a2bc T ktime_add_safe
c006acb4 T ktime_divns
c006aeac T ktime_get_real
c006aee4 T ktime_get_ts
c006af44 T ktime_get


по крайней мере, смотрим определения к ним относящиеся в <linux/ktime.h> заголовках ядра, а операции с ними - <linux/hrtimer.h>


Цитата(xor.kruger @ Mar 1 2012, 11:58) *
Практически все возможные операции (решения) со временем в GNU/Linux описаны в книге Р.Лав "Linux. System Programming" в главе "Time". Может быть найдете там что нибудь полезное.

нет, эта книга устаревшая (относительно), ещё тех времён, когда Р.Лав служил Novell wink.gif
там замечательно описаны все классические механизмы времени (базирующиеся на системном таймере - HZ), но нет ничего о более поздних механизмах.

если говорить о книгах по ядру, то что-то на этот счёт можно найти:

- «Essential Linux Device Drivers», by Sreekrishnan Venkateswaran, Prentice Hall, 2008, p.714.
я не знаю электронной копии этой книги, но есть архив примеров кодов к ней: http://elinuxdd.com/~elinuxdd/elinuxdd.docs/listings/

- «Professional Linux Kernel Architecture (Wrox Programmer to Programmer)», by Wolfgang Mauerer, Wiley Publishing Inc., 2008, p.1335.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.