|
|
  |
Реально достижимая скорость по SPI, Программно-аппаратные трюки для достижения максимальной скорости перед |
|
|
|
Jul 14 2006, 13:01
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(=GM= @ Jul 14 2006, 18:30)  Я привел фрагмент программы, основной цикл, который выполняется точно за то время, как передается (и принимается) байт по SPI. Зачем я его буду проверять на готовность, если я и так знаю, что он готов к приему следующего байта! и терять при этом драгоценные такты. Я НЕ записываю байт до того, как он освободится, я записываю в тот момент, когда он только что стал пустым. Точно также и с принятым байтом. Тады, ой! Я не обратил на этот факт внимание. Хотя все равно это чисто теоретический кусок кода, не имеющий практического применения. В реальности нужны еще кое-какие проверки, хотя бы на окончание буфера, выделенного для приемоперадачи или на количество байт заданных для чтения/записи.
|
|
|
|
|
Jul 14 2006, 13:25
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(unichorn @ Jul 14 2006, 11:39)  Интересный подход. А остальная программа в момент приёма/передачи пакета ничего не делает. PC. Вафли ловит. Да, ничего не делает, она сильно занята(:-)! Отсюда вытекает интереснейший вопрос. Щас я его попробую сформулировать, может его надо бы в отдельную ветку вынести, чтобы не перегружать, ну да ладно. Есть некая микроконтроллерная система, состоящая из нескольких МК, обменивающихся между собой, скажем по SPI. Как лучше сделать обмен, с точки зрения экономии производительности МК, по прерываниям или максимально быстрый программно-аппаратный обмен, как описано мною выше? Поясню на примере, что имею ввиду. Хотим передать 128 байт. При программно-аппаратном обмене мы потеряем 16*128=2048 МЦ. При обмене по прерываниям мы должны учесть вызов прерывания, сохранение/восстановление временного регистра и статуса, возврат из прерывания, плюс такое же тело подпрограммы, если ничего не забыл, то получается не менее 22 МЦ (это если регистры указателей закреплены за данным прерыванием!). Все это надо делать для каждого байта, так что, в сумме будет 22*128=2816 МЦ на каждый обмен. Еще надо учесть, что прерывания должны следовать каждые 22 МЦ, значит максимальная скорость передачи будет ниже. чем при программно-аппаратном обмене! Да еще не забыть, что есть запасные 8 МЦ в каждом цикле, стоит ими грамотно распорядиться(:-). Конечно, экономия копеешная, но иногда ее так не хватает! Вот такой философский вопрос по использованию и НЕ использованию прерываний где попало. Думайте сами, решайте сами, прерывать или не прерывать. И еще, маленькая просьба, пжлст, не пишите РС, если нет подписи, это моветон, не обижайтесь. Okey-dokey?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 13:40
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(rezident @ Jul 14 2006, 12:01)  Цитата(=GM= @ Jul 14 2006, 18:30)  Я привел фрагмент программы, основной цикл, который выполняется точно за то время, как передается (и принимается) байт по SPI. Зачем я его буду проверять на готовность, если я и так знаю, что он готов к приему следующего байта! и терять при этом драгоценные такты. Я НЕ записываю байт до того, как он освободится, я записываю в тот момент, когда он только что стал пустым. Точно также и с принятым байтом.
Тады, ой! Я не обратил на этот факт внимание. Хотя все равно это чисто теоретический кусок кода, не имеющий практического применения. В реальности нужны еще кое-какие проверки, хотя бы на окончание буфера, выделенного для приемоперадачи или на количество байт заданных для чтения/записи. Принято. Что касается проверок. Код приведен практически реальный. Можно было бы, конечно, поставить декремент счетчика байт (но считать можно было бы только до 256, а если мне надо передать 300?) и переход по условию, но тогда было бы 9 МЦ, а у меня 8! Кто может написать быстрее(:-)? Ну ладно, это у меня отпускные настроения разыгрались(:-). А по делу так. Устанавливаете таймер на прерывание точно после последнего переданного байта, вот вам и будет выход из цикла, останется только подчистить верхушку стека...Зато 8 МЦ! Кому они нужны, право? Ну скажем, можно сделать хороший джейтаг для отладки, на АВР с тактовой 20 МГц скорость может достигать 10 мбит/с.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 13:53
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Код <nop x 8 раз или другая задача на 8МЦ> spiLoop: ld txByte,X+;подготавливаем байт на передачу in rxByte,SPDR;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte;запускаем байт на передачу st Y+,rxByte;сохраняем принятый байт в приемном буфере <nop x 6 раз или другая задача на 6МЦ> subi r16,1 sbci r17,0 brcc spiLoop;повторяем цикл Так потянет? 6 тактов в запасе. А в Оксфорде учитесь?
Сообщение отредактировал GetSmart - Jul 14 2006, 13:58
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 13:55
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
=GM=, есть несколько нюансов в описываемой вами схеме. Цитата Есть некая микроконтроллерная система, состоящая из нескольких МК, обменивающихся между собой, скажем по SPI. Как лучше сделать обмен, с точки зрения экономии производительности МК, по прерываниям или максимально быстрый программно-аппаратный обмен, как описано мною выше? В чем смысл гонять данные с максимальной скоростью? А обрабатывать их до/во время/после обмена не нужно? Что приоритетней, задача выполняемая МК или обмен данными? А оба МК будут успевать подавать данные на конвейер синхронного интерфейса? Или достоверность данных вас особо не волнует? Отсюда наверное и будет решение по прерыванию или в цикле организовывать обмен по SPI. Я бы не стал столь рискованно (на пределе возможного) организовывать обмен даже двух МК. Вот если МК и DataFlash с аппаратным конвейером SPI, то это пожалуйста. предложенный вами кусок кода вполне можно имплантировать в программу.
|
|
|
|
|
Jul 14 2006, 14:50
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(rezident @ Jul 14 2006, 12:55)  =GM=, есть несколько нюансов в описываемой вами схеме. Цитата Есть некая микроконтроллерная система, состоящая из нескольких МК, обменивающихся между собой, скажем по SPI. Как лучше сделать обмен, с точки зрения экономии производительности МК, по прерываниям или максимально быстрый программно-аппаратный обмен, как описано мною выше? В чем смысл гонять данные с максимальной скоростью? Конечно, нюансы есть везде. Чёрт, как известно, сидит в деталях(:-). А в чем смысл их гонять с минимальной скоростью(:-)? Выше я показал на примере, что при максимальной скорости есть некая экономия производительности МК. Цитата(rezident @ Jul 14 2006, 12:55)  А обрабатывать их до/во время/после обмена не нужно? Что приоритетней, задача выполняемая МК или обмен данными? А оба МК будут успевать подавать данные на конвейер синхронного интерфейса? Или достоверность данных вас особо не волнует? Ну, типовой АВР не потянет обработать на такой скорости, увы. Вопрос в другом, что лучше ИЛИ быстро принять пакет, затрачивая минимум производительности, ведь последовательная передача - это непроизводственные затраты, и затем обработать принятый пакет? Во многих протоколах нельзя обработать пакет, не приняв его целиком. ИЛИ же обрабатывать пакет побайтно, теряя на производительности, и принимая решение на ходу? Цитата(rezident @ Jul 14 2006, 12:55)  А оба МК будут успевать подавать данные на конвейер синхронного интерфейса? Ну вы же видите, что программа успевает и принять байт и передать его. А следующая передача может случиться через секунду. Ну вот скажем, вы делаете систему тестирования, вы принимаете байты из LPT ПК и хотите передать в JTAG, для проверки некой микросхемы или платы, используя пограничное сканирование. Что вы предпочтете, медленно заталкивать биты в последовательные регистры нескольких микросхем или быстро? Ответ очевиден, быстро (насколько позволяет система) затолкнуть скажем 600 бит, подождать процесса установления, затем протестировать... Цитата(rezident @ Jul 14 2006, 12:55)  Отсюда наверное и будет решение по прерыванию или в цикле организовывать обмен по SPI. Я бы не стал столь рискованно (на пределе возможного) организовывать обмен даже двух МК. Вот если МК и DataFlash с аппаратным конвейером SPI, то это пожалуйста. предложенный вами кусок кода вполне можно имплантировать в программу. Спасибо. Пользуйтесь, мне не жалко. Ну я тоже не сторонник работать на пределе. Жизнь иногда заставляет. Проект был - асик с доморощенным интерфейсом 5 Мбит/с с точностью до 10 нс, передается команда, затем переключение на прием, принимается 32 бита данных, что делать? А я еще клювом прощелкал, мог бы поработать с людьми, изменить интерфейс, асик был заказной, под нас делали..Пришлось извиваться. Сейчас из 150 мкс обмен занимает 35 мкс! Да я ДПФ делаю за 70 мкс! Цитата(GetSmart @ Jul 14 2006, 12:53)  Код spiLoop: ld txByte,X+;подготавливаем байт на передачу in rxByte,SPDR;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte;запускаем байт на передачу st Y+,rxByte;сохраняем принятый байт в приемном буфере <nop x 6 раз или другая задача на 6МЦ> subi r16,1 sbci r17,0 brcc spiLoop;повторяем цикл Так потянет? 6 тактов в запасе. Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Цитата(GetSmart @ Jul 14 2006, 12:53)  А в Оксфорде учитесь? Не, работаю. Занесло вот в ЮКей. Не каждый московский голубь долетит до середины Ламанша(:-).
Сообщение отредактировал =GM= - Jul 14 2006, 14:49
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 14:58
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Я всего-то заменил два NOPа на SUBI+SBCI. Может вы сами просчитались? В вашей проге было 16 МЦ и в моей 16. Отлично, Константин.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 15:16
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(GetSmart @ Jul 14 2006, 13:58)  Цитата Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Я всего-то заменил два NOPа на SUBI+SBCI. Может вы сами просчитались? В вашей проге было 16 МЦ и в моей 16. Немного не так. Цикл исполняется за 16 МЦ, эт-да, нельзя ни убавить, ни прибавить. Но сама прога, вместе с командой перехода занимает 8 МЦ, следовательно, я могу что-то сделать полезное в оставшиеся 8 МЦ. Скажем, передаю 16 байт и одновременно осуществляю распределенное деление 16/16 (как часть другой задачи). Ну или умножение 16*16, не важно. Важно, что время даром не пропадает. Еще можно чего-нить по медленному программному RS-232C передавать, да мало ли что. А когда Атмел поставит второй SPI, то можно было бы и его задействовать на такой же скорости, в то же самое время! Цитата(GetSmart @ Jul 14 2006, 13:58)  Отлично, Константин. Очень приятно, Костя, меня зовут Джордж, GM это мои инициалы.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 15:32
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
1. А кто тогда Георгий? 2. А когда у вас в цикле стоит бесконечный цикл, это по-вашему в порядке вещей. И ещё ремарка, что можно даром время не терять, но считать кол-во переданных байт мы не будем из принципа. ЗЫ. Эффект от "извращений" пропорционален скорости проца, ну и его стоимости. Для АВРа как-то мелко получается. Цитата Важно, что время даром не пропадает. Ну так определитесь что будете делать уже. А то я могу ещё 2 МЦ в копилку добавить. А если очень захотите, то и передавать на 8 других процессоров одновременно.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 15:57
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(GetSmart @ Jul 14 2006, 14:32)  1. А кто тогда Георгий? Какой Георгий? А-а, Григорий! Это из юморески ММЖ, вы там просто смайлик не заметили! А вообще у меня Джордж-джуниор, т.е. Георгий, подрастает. Цитата(GetSmart @ Jul 14 2006, 14:32)  2. А когда у вас в цикле стоит бесконечный цикл, это по-вашему в порядке вещей. И ещё ремарка, что можно даром время не терять, но считать кол-во переданных байт мы не будем из принципа. Ну уже ответил, см. пост №19, отвечу здесь. Устанавливаете таймер на прерывание точно после последнего переданного байта, вот вам и будет выход из цикла, останется только подчистить верхушку стека...Вот вам и 8 МЦ, вместо 9 или ваших 10! Цитата(GetSmart @ Jul 14 2006, 14:32)  ЗЫ. Эффект от "извращений" пропорционален скорости проца, ну и его стоимости. Для АВРа как-то мелко получается. Это я не понимаю, это не ко мне. Цитата(GetSmart @ Jul 14 2006, 14:32)  Цитата Важно, что время даром не пропадает. Ну так определитесь что будете делать уже. А то я могу ещё 2 МЦ в копилку добавить. А если очень захотите, то и передавать на 8 других процессоров одновременно. Вот интересно, покажите, как это сделать. На 8 процессоров тоже интересно (теоретически). Но думаю вы шутите, это какое-то чудо передать на 8 процов одновременно на скорости 10 мбит/с. Надеюсь, передается индивидуальная для каждого проца информация?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 16:16
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата Надеюсь, передается индивидуальная для каждого проца информация? Ну разумээтся. Не чудо. Только в одну сторону. Ну и со скоростью 6.666 мбит. Так ведь можно? (делитель 1/3) Ну или 1/4. Подумайте денёк. Может догадаетесь. Цитата Не каждый московский голубь долетит до середины Ламанша(:-) Хммм... Хотя постойте. Принимать-таки можно. Можно с одного. А можно с одного из восьми. Ну или со скольки угодно. Пардон. 6.666 МБАЙТ.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 16:27
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(GetSmart @ Jul 14 2006, 15:16)  Цитата Надеюсь, передается индивидуальная для каждого проца информация? Ну разумээтся. Не чудо. Только в одну сторону. Ну и со скоростью 6.666 мбит. Так ведь можно? (делитель 1/3) Ну или 1/4. Подумайте денёк. Может догадаетесь. Пардон. 6.666 МБАЙТ. Прошу пардону. Дайте постановку задачи. Что за делитель, что за 6,(6)Мбайт...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 17:21
|
Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821

|
2 ksv198 Цитата Поэтому все правильно - сначала пишем в SPDR, потом читаем. Чего-то я не допираю, счего вдруг сначала писать, а потом читать. Тем не менее мой вариант: Код ld r19,X _spi_loop: in r18,SPDR ;1 out SPDR,r19 ;1 st X+,r18 ;2 ld r19,X ;2 _spi_wait_spif: sbis SPSR,SPIF ;1 2 rjmp _spi_wait_spif;2 dec r16 ;1 brne _spi_loop ;2 1 итого: Замечу, что проверка флага - вышло неудачно. 6 nop у GetSmart эффективнее 2 =GM= Цитата Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Зато у GetSmart с проверкой количества байт. P.S. Приведенный код может содержать ошибки, укажите пожалуйста если таковые будут обнаружены. P.P.S. Мне вообще кажется, что довольно трудно оптимизировать программу на RISC, кроме случаев когда она писалась бездумно  .
--------------------
Чудес не бывает - бывает мало знаний и опыта!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|