2013-01-04 2 views
2

Я использую ARM Cortex-A8 и пытаюсь прочитать значение из счетчика времени CCNT через код сборки. Я следую за этим сообщением How to measure program execution time in ARM Cortex-A8 processor?. В соответствии с этим, прежде чем я смогу прочитать значение с таймера, мне нужно включить счетчик, включить 64-разрядный делитель и прозрачные переполнения. Эти операции выполняются путем записи внутри соответствующих регистров (например, PMCR (Performance Monitro Control Register)). Итак, я распечатаны значения счетчика в цикле, чтобы следить, как происходит переполнение, и у меня есть такое поведение:время выполнения программы в процессоре ARM Cortex-A8

1           (starts to incrementing after it was reset to zero) 
4650 
4858 
4943 
5023 
... 
...        (incrementing...) 
... 
4293939054 
4293939128       (overflow happens) 
1602570          
1602703 
1602788 
... 
... 
4293522911 
4293522987 
4293523062 
4293523137 
1186243 
1186367 
1186453 
1186536 
1186612 
1186686 
... 
4293536300 
4293536377 
4293536456 
4293536533 
4293536612 
1199090 
1199209 
1199295 
1199373 
1199453 
1199530 
…. 
and so forth. 

Соответственно, у меня есть ряд вопросов:

а) Что или упомянутые выше регистров используются ядром Linux? (насколько надежна информация для дальнейших версий ядра). Насколько безопасным может быть изменение их ценностей?

b) Какова точность значения частоты CCNT и как ее получить? К сожалению, я не могу найти значение в спецификации процессора. Тем не менее, dmesg говорит, что

[ 0.000000] OMAP clocksource: GPTIMER2 at 24000000 Hz 
[ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms 
[ 0.132855] Switching to clocksource gp timer 

Но отождествляя его вручную, против clock_gettime, дает мне 7 МГц. Итак, почему это не 24 МГц, как ожидалось?

c) Согласно моему первому выпуску, почему после переполнения оно начинается не с нуля, а от примерно 1 мил?

d) Почему без 64 ​​разделителей я получаю неправильные результаты? Значение начинает скачковаться таким образом:

... 
134110099 
134114934 
134119656 
302352300 
302361825 
302367135 
… 
2885588930 
2885593776 
2885598630 
3053958670 
3053966752 
3053972232 
… 
261130096 
261134909 
429343853 
429351487 
429356735 

Буду признателен за любую помощь. Спасибо

ответ

4

a) Регламенты PMU могут использоваться первичной подсистемой ядра Linux (доступ к которой осуществляется через инструмент простого пользовательского пространства).

b) Частота CCNT - это счетчик циклов процессора Cortex-A9 или циклов/64, если вы активируете разделитель. Таким образом, 7MHz с делителем будет средней частотой процессора около 450 МГц. Это отдельно от системных часов 24 МГц.

c) Возможно, ваш процесс был запланирован. Это низкоуровневый счетчик циклов для всего процессора, а не только для вашего процесса. Он будет работать в ядре или в другом процессе. С другой стороны, если ваш процесс переносится на другой процессор, вы будете получать доступ к счетчику циклов процессора (который может даже не иметь одинаковую настройку делителя). Если вы хотите согласовать счет, вы должны привязать свой процесс к одному процессору.

d) аналогичный ответ на (c), вы можете видеть эффект планирования процесса и миграции.

+1

Благодарим за быстрый ответ. Что касается б) - Мой вопрос, почему я получаю 7 МГц (450 МГц)? Я ожидал, что CCNT - это системные часы, и я получил его частоту 24 МГц? Моя цель - избежать системного вызова и получить доступ к предпочтительным часам ядра, и я думал, что это CCNT. Если нет, как я могу получить доступ к системным часам? – Irina

+0

Нет, CCNT управляется из циклов процессора (возможно, разделен на 64). Частота процессора может варьироваться в зависимости от DVFS (динамическое масштабирование напряжения/частоты). Если вы хотите прочитать таймер, работающий с постоянной частотой, вам нужно получить доступ к глобальному таймеру, а не к CCNT. –