Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Производительность SAM9XE
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
EugenB2
Имеется платка с SAM9XE512, все запускает, шьется, работает. Но есть одно неприятное НО. Решил я затестить производительность сей штуки. Сделал тупо просто:
t=GetTickCount(); 1ms тики
for(k=0;k < 6600000; k++); подобрал, чтобы 1секунду примерно
t=GetTickCount()-t; равно 1000
(вообще сделал вывод в DEBUG и компом проверил отсчет 1 секунды)

Итак получаем в дизасме(позже выложу), что цикл занимает 5 инструкций, одна из них 2такта . Итого 7 тактов.
Итак 7*6600000=46200000 46 MIPS
Потом включаю ICache. Вуаля, производительность сразу в два раза 92мипса.
А теперь вопрос! Где обещанные 200MIPS????? Или я где-то ошибся?
AlexandrY
Классическая ошибка. ICache включить недостаточно, надо сконфигурировать MMU еще, сделать мапинг на этот код и там указать кэширование.
Цитата(EugenB2 @ Jan 14 2010, 23:01) *
Потом включаю ICache. Вуаля, производительность сразу в два раза 92мипса.
EugenB2
Цитата(AlexandrY @ Jan 14 2010, 23:35) *
Классическая ошибка. ICache включить недостаточно, надо сконфигурировать MMU еще, сделать мапинг на этот код и там указать кэширование.

Спасибо, покопаю в этом направлении.
AlexandrY
Интересно в какой среде вы работаете. В IAR-е в их примерах так сразу эту операцию делают с MMU.
Цитата(EugenB2 @ Jan 15 2010, 00:00) *
Спасибо, покопаю в этом направлении.
vmp
Может быть пригодится - производительность SAM9XE в разных условиях:
http://caxapa.ru/144973.html
EugenB2
Цитата(AlexandrY @ Jan 15 2010, 00:03) *
Интересно в какой среде вы работаете. В IAR-е в их примерах так сразу эту операцию делают с MMU.

Как раз им и пользуюсь, но ничего такого в коде и не видел.
EugenB2
Почитал даташит по MMU, понял, что можно закопаться в написании с нуля сего дела. Полазил по форуму, по гуглу, что-то нет примеров реализации MMU. Может, у кого есть чего?
AlexandrY
Да не, в IAR-е полно этого добра. Только для Atmel-ов нет.
Дело видимо в том, что Atmel-ы плотно пасет Adeneo и из бесплатных сорсов повытягивал все что только можно чтобы усложнить самостоятельный стартап на Atmel-ах.
Смотрите файлы ttbl.c в других директориях IAR-а. И по аналогии можете создать свой для Atmel-а.
А лучше переходите сразу на NXP. Меньше дурных проблем будет.

Цитата(EugenB2 @ Jan 15 2010, 10:40) *
Почитал даташит по MMU, понял, что можно закопаться в написании с нуля сего дела. Полазил по форуму, по гуглу, что-то нет примеров реализации MMU. Может, у кого есть чего?
andrewlekar
То есть я так понял атмеловские примеры для армов работают с производительностью в два раза меньше чем могли бы? Это именно для процов с поддержкой MMU?
EugenB2
Цитата(andrewlekar @ Jan 15 2010, 12:23) *
То есть я так понял атмеловские примеры для армов работают с производительностью в два раза меньше чем могли бы? Это именно для процов с поддержкой MMU?

Получается что да, если с MMU. Ищу вот пример реализации...

Цитата(AlexandrY @ Jan 15 2010, 10:56) *
Да не, в IAR-е полно этого добра. Только для Atmel-ов нет.
Дело видимо в том, что Atmel-ы плотно пасет Adeneo и из бесплатных сорсов повытягивал все что только можно чтобы усложнить самостоятельный стартап на Atmel-ах.
Смотрите файлы ttbl.c в других директориях IAR-а. И по аналогии можете создать свой для Atmel-а.
А лучше переходите сразу на NXP. Меньше дурных проблем будет.

Да полно уже нароботок на SAM7S, а вот с NXP тоже не так все гладко. Там оказывается, что ДМА реализован совершенно не так, как в атмелах. Есть несколько каналов ДМА на ВСЮ периферию и крутись как хочешь. Вот у меня были потоковые приложения, где вводилась инфа через 4 порта посредством PDC на постоянке. А если бы на NXP, то все, уперся бы в стену. Потому как каналы все были бы заняты.
Но зато в NXP есть DMA SRAM to SRAM... )) и нет глюков с периферией таких.
andrewlekar
А почему для указанного кода недостаточно I-Cache? Как там поможет кэш данных, если данные особо не используются?
vmp
Пример инициализации MMU для SAM9XE под IAR 5.x
Раскладка ОЗУ - кешируются 31 мегабайт из 32, последний мегабайт оставлен для буферов при работе с DMA (некешируемый).
Секцию "TLB" нужно задать в .icf - файле, я ее клал в последние 16К последнего мегабайта ОЗУ (в некешируемую область), с адреса 0x21FFC000.
andrewlekar
Цитата(vmp @ Jan 15 2010, 16:32) *
Пример инициализации MMU для SAM9XE под IAR 5.x
Раскладка ОЗУ - кешируются 31 мегабайт из 32, последний мегабайт оставлен для буферов при работе с DMA (некешируемый).
Секцию "TLB" нужно задать в .icf - файле, я ее клал в последние 16К последнего мегабайта ОЗУ (в некешируемую область), с адреса 0x21FFC000.

То есть секция TLB у вас размещалась в SDRAM? Это не слишком било по производительности? Разглядываю примеры - там располагали эту секцию в SRAM.
defunct
Цитата(EugenB2 @ Jan 14 2010, 23:01) *
Потом включаю ICache. Вуаля, производительность сразу в два раза 92мипса.
А теперь вопрос! Где обещанные 200MIPS????? Или я где-то ошибся?

Настройте MMU, включите DCache, настройте Bus Matrix. И выйдете на 200MIPS.

Для примера.
Простой пакетный bridge на XE512 с включенным одним только ICache - обрабатывает 7K пакетов в секунду. А с настроенным BusMatrix'ом, MMU, и включенным DCache - 30K пакетов в секунду.
EugenB2
Цитата(andrewlekar @ Jan 15 2010, 13:06) *
А почему для указанного кода недостаточно I-Cache? Как там поможет кэш данных, если данные особо не используются?

Cам в догадках...
\ ??testit_0:
\ 00000008 10109FE5 LDR R1,??testit_1 ;; 0xd59f80 единственное обращение к памяти, а производительности особо не прибавилось
\ 0000000C 010050E1 CMP R0,R1
\ 00000010 0100002A BCS ??testit_2
\ 00000014 010090E2 ADDS R0,R0,#+1
\ 00000018 FAFFFFEA B ??testit_0
468 }
\ ??testit_2:
\ 0000001C 1EFF2FE1 BX LR ;; return
vmp
Цитата(andrewlekar @ Jan 15 2010, 14:41) *
То есть секция TLB у вас размещалась в SDRAM? Это не слишком било по производительности? Разглядываю примеры - там располагали эту секцию в SRAM.

Не проверял. Но вообще-то она кешируется, в ARM926EJ-S кеш TLB имеет по 32 элемента на код и данные, так что для данной конфигурации почти все должно было осесть в кеше.
defunct
Цитата(andrewlekar @ Jan 15 2010, 13:41) *
То есть секция TLB у вас размещалась в SDRAM? Это не слишком било по производительности? Разглядываю примеры - там располагали эту секцию в SRAM.

Это совершенно не бъет по производительности если суммарное количество активных секций (та память с которой работаем) не превашает 64 (напр 64 секции по 1MB). Активные секции постоянно будут в регистрах MMU и обращений к TLB практически не будет.
EugenB2
Цитата(vmp @ Jan 15 2010, 13:32) *
Пример инициализации MMU для SAM9XE под IAR 5.x
Раскладка ОЗУ - кешируются 31 мегабайт из 32, последний мегабайт оставлен для буферов при работе с DMA (некешируемый).
Секцию "TLB" нужно задать в .icf - файле, я ее клал в последние 16К последнего мегабайта ОЗУ (в некешируемую область), с адреса 0x21FFC000.

Спасибо за файлик. После некоторых его исправлений я наконец-то получил таки мои 200мипсов!
Я так подумал, а почему бы не разместить TLB таких объемов во FLASH(и ОЗУ не надо тратить и должно врое работать все), и разместил, залил вуаля, все также нормально(вроде нормально) работает.
Нажмите для просмотра прикрепленного файла
EugenB2
Ндаа. Радость была недолгой. Вставил во FreeRTOS, после prvSetupTimerInterrupt - это конфиг таймера шедулера - зависает все ((.

подправил исходничек и вуаля на FreeRTOS тоже заработало
Нажмите для просмотра прикрепленного файла

==============
Кстати, что за глюк форума, не дает отредактировать сообщение.
sasamy
Цитата(defunct @ Jan 15 2010, 15:37) *
Это совершенно не бъет по производительности если суммарное количество активных секций (та память с которой работаем) не превашает 64 (напр 64 секции по 1MB). Активные секции постоянно будут в регистрах MMU и обращений к TLB практически не будет.


Зря вы таблицу страниц назваете TLB smile.gif TLB - это как раз тот самый ассоциативный кэш из 64 регистров к которым и будем обращение. Translation Lookaside Buffer.
sasamy
Цитата(EugenB2 @ Jan 15 2010, 16:20) *
Cам в догадках...
\ ??testit_0:
\ 00000008 10109FE5 LDR R1,??testit_1 ;; 0xd59f80 единственное обращение к памяти, а производительности особо не прибавилось
\ 0000000C 010050E1 CMP R0,R1
\ 00000010 0100002A BCS ??testit_2
\ 00000014 010090E2 ADDS R0,R0,#+1
\ 00000018 FAFFFFEA B ??testit_0
468 }
\ ??testit_2:
\ 0000001C 1EFF2FE1 BX LR ;; return


Может я и не прав - у arm9 кэши логические - они работают с логичсескими адресами, а таблицы страниц не что иное как данные, в совокупности с тем что 926 в отличие от 720 имеют гарвардскую архитектуру им нужно и кэш данных включать.
aaarrr
Цитата(sasamy @ Jan 16 2010, 21:38) *
Может я и не прав - у arm9 кэши логические - они работают с логичсескими адресами, а таблицы страниц не что иное как данные, в совокупности с тем что 926 в отличие от 720 имеют гарвардскую архитектуру им нужно и кэш данных включать.

Вы сами-то поняли, что хотели сказать?
sasamy
Цитата(aaarrr @ Jan 17 2010, 14:17) *
Вы сами-то поняли, что хотели сказать?


Согласен - ерунду полную сморозил smile.gif
V_M_Luck
Уважаемый vmp!
Возвращаясь к вашему примеру, не могли бы вы пояснить, как имеено связаны биты C и B описания секций с областью DMA? Интуитивно понятно, но чем все-таки это чревато?

Уважаемый vmp!
Возвращаясь к вашему примеру, не могли бы вы пояснить, как имеено связаны биты C и B описания секций с областью DMA? Интуитивно понятно, но чем все-таки это чревато?
aaarrr
Цитата(V_M_Luck @ Feb 9 2010, 15:24) *
Уважаемый vmp!
Возвращаясь к вашему примеру, не могли бы вы пояснить, как имеено связаны биты C и B описания секций с областью DMA? Интуитивно понятно, но чем все-таки это чревато?

Я хоть и не vmp, но отвечу smile.gif

Рассмотрим два случая:

1. DMA пишет в память. В том случае, если DMA производит запись в область памяти, для которой включено кэширование (любого типа), то существует ненулевая вероятность, что ядро при чтении поднимет данные из кэша, вместо обращения к памяти. То есть для нормальной работы придется полностью или частично сбрасывать кэш перед чтением.

2. DMA читает из памяти. Здесь мы наблюдаем обратный эффект: в памяти могут содержаться устаревшие с точки зрения ядра данные, если кэш сконфигурирован в режиме write-back.
V_M_Luck
Спасибо за ответ.
Это в общем-то понятно. Вопрос возник вот почему. Я, разбираясь в этом вопросе провожу некоторые эксперименты. Я настроил UART на выдачу через PDC. Ну и шлю на ПК строчки. Без ММУ и кэшей все работает. Подключаю ММУ, все ОЗУ - одним сектором, кэш и буферизация включены, DCash, ICASH включены - все ОК. Отключаю DCash - тоже работает, но начинает глючить дебаггер. Отключаю кэш и буферизацию в ММУ - не работает! Вишу в Data abort.
Как же корректно сконфигурировать ММУ и кэши для использования DMA?
aaarrr
Цитата(V_M_Luck @ Feb 9 2010, 15:54) *
Вишу в Data abort.

Посмотрите, откуда падаете в Data Abort. Связь с кэшем тут если и есть, то весьма опосредованная.
defunct
Цитата(sasamy @ Jan 16 2010, 11:04) *
Зря вы таблицу страниц назваете TLB smile.gif TLB - это как раз тот самый ассоциативный кэш из 64 регистров к которым и будет обращение. Translation Lookaside Buffer.

За поправку спасибо!
нутром чуял что что-то не то, но теоретической базы полную истину изобразить нехватило. sad.gif

В моем посте имелось в виду, что не будет обращений к Translation Table (TT) - той что лежит в памяти.
vmp
Цитата(V_M_Luck @ Feb 9 2010, 15:54) *
Как же корректно сконфигурировать ММУ и кэши для использования DMA?

Пример я уже давал выше. Буфера надо располагать в некешируемой области - для данного примера это от 0x21F00000 до 0x21FFBFFF.
В некешируемой области биты С и B должны быть равны 0 (некешируемая и небуферируемая).
Еще раз обращаю винмание на тонкость с переадресацией 0-х адресов - их надо отображать в 0x00200000 (флеш), иначе не работают прерывания.
Data Abort - возможно, вы настроили не всю таблицу.
То, что у вас работал PDC из кешируемой памяти - либо просто везение (эти адреса не лежали в кеше), либо неправильная настройка (кеш был выключен или эта область памяти не кешировалась).
V_M_Luck
Цитата(aaarrr @ Feb 9 2010, 16:57) *
Посмотрите, откуда падаете в Data Abort. Связь с кэшем тут если и есть, то весьма опосредованная.

Попадаю из первого обращения к стеку.
Я пользуюсь примером EugenB2. Единственное, я маплю адреса Boot Memory на Flash, поэтому первая запись TT 0x00000C1A.
Когда отключаю DCache, убираю запись в TT 0x00300C1E (SRAM) - попадаю в Data Abort. То же, если TT не исправлять.
Цитата(vmp)
Пример я уже давал выше. Буфера надо располагать в некешируемой области - для данного примера это от 0x21F00000 до 0x21FFBFFF.

Если использовать SRAM, то необходимо его дробить на мелкие страницы?
vmp
Цитата(V_M_Luck @ Feb 10 2010, 10:38) *
Я пользуюсь примером EugenB2. Единственное, я маплю адреса Boot Memory на Flash, поэтому первая запись TT 0x00000C1A.

В третий раз повторяю - первая запись должна быть 0x00200C1A.
Цитата(V_M_Luck @ Feb 10 2010, 10:38) *
Если использовать SRAM, то необходимо его дробить на мелкие страницы?

Зачем? Его и так мало. Тогда проще вообще не заморачиваться с кешированием, оставить только один I-cache, который не требует включения MMU.
aaarrr
Цитата(V_M_Luck @ Feb 10 2010, 10:38) *
Попадаю из первого обращения к стеку.

Куда в этот момент указывает SP?

Цитата(V_M_Luck @ Feb 10 2010, 10:38) *
Я пользуюсь примером EugenB2. Единственное, я маплю адреса Boot Memory на Flash, поэтому первая запись TT 0x00000C1A.

Режим кэширования (WB или WT) никакого значения не имеет.

Цитата(V_M_Luck @ Feb 10 2010, 10:38) *
Когда отключаю DCache, убираю запись в TT 0x00300C1E (SRAM) - попадаю в Data Abort. То же, если TT не исправлять.

Очень похоже, что вы пытаетесь обратиться к памяти, которой физически не существует. Кэш в режиме WT просто маскирует этот косяк. Попробуйте исправить запись на 0x00300C1A - должны тоже получить abort.

Цитата(V_M_Luck @ Feb 10 2010, 10:38) *
Если использовать SRAM, то необходимо его дробить на мелкие страницы?

Нет.

Цитата(vmp @ Feb 10 2010, 10:52) *
В третий раз повторяю - первая запись должна быть 0x00200C1A.

Еще раз спрашиваю: почему? Ответ "потому что иначе не работают прерывания" совершенно не устраивает.


Цитата(vmp @ Feb 10 2010, 09:32) *
В некешируемой области биты С и B должны быть равны 0 (некешируемая и небуферируемая).

Ну, буферизацию как раз можно оставить - зачем гробить производительность окончательно? Благо буфер записи легко очистить перед запуском DMA.
V_M_Luck
Похоже, что все-таки я неправильно настраивал ТТ.
Вариан тпервых записей, с которыми я мог отключать и подключать DCache:
0x00200C1A, 0x00100C1A,0x00200C1A,0x00300C1E
Цитата(aaarrr @ Feb 10 2010, 11:21) *
Еще раз спрашиваю: почему? Ответ "потому что иначе не работают прерывания" совершенно не устраивает.

Первая запись существенна. Хотя действительно, это совершенно не очевидно.
Цитата(aaarrr @ Feb 10 2010, 11:21) *
Нет.

Я имел ввиду, если под DMA выделить часть SRAM, отключив в ней кэширование и буферизацию.
В общем я так и сделал. Описал таблицу дескрипторов второго уровня и дал 1 КБ SRAM под DMA.

Кстати: в PDC нужно указывать физические, а не виртуальные адреса. Как-то не удобно...


Похоже, что все-таки я неправильно настраивал ТТ.
Вариан тпервых записей, с которыми я мог отключать и подключать DCache:
0x00200C1A, 0x00100C1A,0x00200C1A,0x00300C1E
Цитата(aaarrr @ Feb 10 2010, 11:21) *
Еще раз спрашиваю: почему? Ответ "потому что иначе не работают прерывания" совершенно не устраивает.

Первая запись существенна. Хотя действительно, это совершенно не очевидно.
Цитата(aaarrr @ Feb 10 2010, 11:21) *
Нет.

Я имел ввиду, если под DMA выделить часть SRAM, отключив в ней кэширование и буферизацию.
В общем я так и сделал. Описал таблицу дескрипторов второго уровня и дал 1 КБ SRAM под DMA.

Кстати: в PDC нужно указывать физические, а не виртуальные адреса. Как-то не удобно...
aaarrr
Цитата(V_M_Luck @ Feb 10 2010, 15:21) *
Первая запись существенна. Хотя действительно, это совершенно не очевидно.

Пока не станет очевидно, все действия можно приравнять к битью в бубен.
Мапить что-то вручную в нулевой адрес может понадобится только в двух случаях:
1. Если не установлен GPNVM[3], но тогда процессор стартовал бы с ROM
2. Если "случайно" выполняется ремап

Цитата(V_M_Luck @ Feb 10 2010, 15:21) *
Я имел ввиду, если под DMA выделить часть SRAM, отключив в ней кэширование и буферизацию.
В общем я так и сделал. Описал таблицу дескрипторов второго уровня и дал 1 КБ SRAM под DMA.

Понятно.

Цитата(V_M_Luck @ Feb 10 2010, 15:21) *
Кстати: в PDC нужно указывать физические, а не виртуальные адреса. Как-то не удобно...

Зато абсолютно логично. Не знает периферия о виртуальных адресах ничего.
V_M_Luck
Цитата
2. Если "случайно" выполняется ремап

Что вы имеете в виду?
Я использую как основу Atmel пример. Там в board_lowlevel.c был вызов BOARD_RemapRam(); - я его закоментарил. На всякий случай проверяю на старте GPNVM[3] бит. Еще есть лазейки для "случайного" ремапа?
aaarrr
Цитата(V_M_Luck @ Feb 10 2010, 15:56) *
Еще есть лазейки для "случайного" ремапа?

Нет, но проверьте на всякий случай MATRIX_MRCR. Кроме того, следует учитывать, что remap существует только для ядра, периферия (например, PDC) будет всегда использовать обычную карту памяти - тоже потенциальный источник ошибки, правда, не в данном случае.

При обычном раскладе по адресам 0x000000 и 0x200000 будет находится одно и то же содержимое, что исключает необходимость манипуляций с MMU для отражения flash в 0.
V_M_Luck
Большое спасибо за ответы! a14.gif
vmp
Цитата(aaarrr @ Feb 10 2010, 12:21) *
Еще раз спрашиваю: почему? Ответ "потому что иначе не работают прерывания" совершенно не устраивает.

Все-таки полез разбираться в работающую программу. smile.gif
Действительно у меня стартап включал ремап. Поскольку программа была слинкована на адреса ПЗУ (0x00200000), то ей было все равно, включен ремап или нет. После отключения ремапа программа работает как с TLB[0] = 0x00200C1A, так и с TLB[0] = 0x00000C1A.
aaarrr
Славно, ПСС найдены, все встало на свои места smile.gif
sulsher
а не подскажите пример решения данной проблемы на ассемблере?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.