Jump to content

    
Sign in to follow this  
Kris2007

Прочитать точный счетчик из пространства пользователя(rdtsc)

Recommended Posts

Нужно поюзать какой-нибудь точный счетчик циклов из-под ОС Linux из пространства пользователя.

Кроме clock_gettime ничего в голову не приходит. Существует ли какой-нибудь счетчик типа rdtsc для x86, который можно использовать из пространства пользователя(для включения которого не нужен kernel mode)?

 

 

Share this post


Link to post
Share on other sites
Нужно поюзать какой-нибудь точный счетчик циклов из-под ОС Linux из пространства пользователя.

Кроме clock_gettime ничего в голову не приходит. Существует ли какой-нибудь счетчик типа rdtsc для x86, который можно использовать из пространства пользователя(для включения которого не нужен kernel mode)?

 

если это x86, то нет ничего проще ;)

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).

 

если это другая платформа, то там всё зависит от специфики, но по аналогии вы можете сделать такое же.

 

Share this post


Link to post
Share on other sites

ОС Андроид, платформа ARM(конкретные процессоры я предполагаю будут разнообразные), суть вопроса именно(!) как сделать по-аналогии для ARM.

Share this post


Link to post
Share on other sites
(для включения которого не нужен 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?

 

Share this post


Link to post
Share on other sites

Да развернул.

clock_gettime(другого решения пока не нашел( ) насколько я понимаю использует системный вызов sys_timer_gettime.

Но это много дольше, чем просто прочитать регистр таймера в x86(

 

 

Share this post


Link to post
Share on other sites
clock_gettime(другого решения пока не нашел( ) насколько я понимаю использует системный вызов sys_timer_gettime.

 

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

 

Но это много дольше, чем просто прочитать регистр таймера в x86(

при чём здесь вообще "дольше" или "короче" при таких элементарных операциях?

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

 

 

Share this post


Link to post
Share on other sites
[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(), андроиде подобной увы нет.

Share this post


Link to post
Share on other sites
Это критичный момент. Код портируется на много платформ x86, mips, porepc, IOS(на ARM) и т п для всех своя реализация на асме. Для IOS через функцию mach_absolute_time(), андроиде подобной увы нет.

подождите! ;) - это не критичный момент!

 

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

 

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

 

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

- и тогда у вас даже мыслей дурных не будет возникать: портируется - не портируется.

 

P.S. что касается iOS, то это слишком широкое спектр портирования, и тут вам придётся чего-то изобретать, но ... уже на сегодня объём смартфонов под iOS меньше Android (который Linux) скоро в 3 раза и это соотношение только усугубляется.

 

Share this post


Link to post
Share on other sites

Практически все возможные операции (решения) со временем в GNU/Linux описаны в книге Р.Лав "Linux. System Programming" в главе "Time". Может быть найдете там что нибудь полезное.

Share this post


Link to post
Share on other sites
Нужна.

посмотрите тогда, для начала, на таймеры ядра высокого разрешения (как их назвали - появились они с ядра 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>

 

 

Практически все возможные операции (решения) со временем в GNU/Linux описаны в книге Р.Лав "Linux. System Programming" в главе "Time". Может быть найдете там что нибудь полезное.

нет, эта книга устаревшая (относительно), ещё тех времён, когда Р.Лав служил Novell ;)

там замечательно описаны все классические механизмы времени (базирующиеся на системном таймере - 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.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this