Перейти к содержанию
    

jcxz

Свой
  • Постов

    13 823
  • Зарегистрирован

  • Посещение

  • Победитель дней

    38

Весь контент jcxz


  1. Пожалуйста: ;* GLOBAL FILE PARAMETERS * ;* * ;* Architecture : TMS320C674x * ;* Optimization : Enabled at level 3 * ;* Optimizing for : Speed * ;* Based on options: -o3, no -ms * ;* Endian : Little * ;* Interrupt Thrshld : 3000 * ;* Data Access Model : Far Aggregate Data * ;* Pipelining : Enabled * ;* Speculate Loads : Disabled * ;* Memory Aliases : Presume are aliases (pessimistic) * ;* Debug Info : DWARF Debug for Program Analysis w/Optimization * Не знаю как у вас получилось "No Debug Info", у меня в свойствах проекта отключена debug info везде где можно (и в опциях компилятора и линкёра). Похоже - не совсем так. Я, как Вы советовали, убрал сдвиги из цикла, в результате - кол-во команд в теле цикла значительно уменьшилось, и загрузка процессора заметно уменьшилась. Но заголовок цикла остался тем-же: "SPLOOPD 4 ;16" см. результаты замеров ниже. Я пробовал ставить его ==64 - тело цикла не меняется ни на команду. Вот тело цикла с _sshl(): SPLOOPD 4 ;16 ; (P) || SUB .L1 A3,8,A16 || SUB .D1 A3,16,A3 || MVC .S2X A4,ILC ;** ------------------------------------------------------------ $C$L4: ; PIPED LOOP KERNEL $C$DW$L$_DSPF_fltoq31__FPCfPii$7$B: LDW .D1T1 *A3--(16),A7; |121| (P) <0,0> || LDW .D2T2 *B6--(16),B16; |122| (P) <0,0> LDW .D1T1 *A16--(16),A8; |123| (P) <0,1> || LDW .D2T2 *B9--(16),B8; |125| (P) <0,1> NOP 3 MPYSP .M1 A17,A7,A6; |121| (P) <0,5> || MPYSP .M2X A17,B16,B8 ; |122| (P) <0,5> MPYSP .M1 A17,A8,A6; |123| (P) <0,6> || MPYSP .M2X A17,B8,B5; |125| (P) <0,6> SPMASK D2 || SUB .D2 B10,16,B10 SPMASK L2,S2 || MV .L2 B10,B4 || MV .S2 B10,B7 SPMASK S1 || MV .S1X B10,A5 || SPINT .L1 A6,A8 ; |121| (P) <0,9> || SPINT .L2 B8,B5 ; |122| (P) <0,9> SPMASK S1,D1,S2 || ADDK .S2 24,B7 || MV .D1X B10,A4 || ADDK .S1 28,A5 || SPINT .L1 A6,A9 ; |123| (P) <0,10> || SPINT .L2 B5,B17 ; |125| (P) <0,10> SPMASK S1,S2 || ADDK .S2 16,B4 || ADDK .S1 20,A4 NOP 1 SSHL .S2 B5,8,B16 ; |127| <0,13> || SSHL .S1 A8,8,A7 ; |128| <0,13> STW .D2T2 B16,*B7++(16); |127| <0,14> || STW .D1T1 A7,*A5++(16); |128| <0,14> || SSHL .S1 A9,8,A6 ; |126| <0,14> || SSHL .S2 B17,8,B5 ; |125| <0,14> .dwpsn file "DSPF_fltoq31.c",line 129,column 0,is_stmt SPKERNEL 3,0 || STW .D1T1 A6,*A4++(16); |126| <0,15> || STW .D2T2 B5,*B4++(16); |125| <0,15> Вот - без _sshl(): SPLOOPD 4 ;16 ; (P) || MVC .S2X A4,ILC ;** ----------------------------------------------------------- $C$L4: ; PIPED LOOP KERNEL $C$DW$L$_DSPF_fltoq31__FPCfPii$7$B: SPMASK L2 || ADD .L2X 8,A3,B5 || LDNDW .D1T1 *A3--(16),A9:A8; |124| (P) <0,0> LDNDW .D2T2 *B5--(16),B9:B8; |122| (P) <0,1> NOP 3 MPYSP .M1 A7,A8,A4 ; |124| (P) <0,5> MPYSP .M2X A7,B8,B6 ; |122| (P) <0,6> || MPYSP .M1 A7,A9,A8 ; |124| (P) <0,6> MPYSP .M2X A7,B9,B8 ; |122| (P) <0,7> NOP 1 SPINT .L1 A4,A5 ; |124| (P) <0,9> SPINT .L2 B6,B7 ; |122| (P) <0,10> || SPINT .L1 A8,A4 ; |124| (P) <0,10> SPMASK L1,S2 || MV .S2 B10,B4 || ADD .L1X 8,B10,A6 || SPINT .L2 B8,B6 ; |122| (P) <0,11> NOP 2 STNDW .D1T1 A5:A4,*A6++(16); |124| <0,14> .dwpsn file "DSPF_fltoq31.c",line 125,column 0,is_stmt SPKERNEL 3,0 || STNDW .D2T2 B7:B6,*B4++(16); |122| <0,15> Загрузка процессора (на этой функции) уменьшилась на 40% !!! Т.е. - в первом варианте полная загрузка процессора задачей составляла == 8.8% Во-втором варианте полная загрузка процессора задачей == 8.2% При закомментировании этой функции (выполняется только остальная обработка) == 7.3% Хотя - если посчитать по командам - оба варианта должны быть одинаковы.... Код функции и вх. данные линкуются во внутреннюю L2-память, выходные данные - во внутренней L3-памяти.
  2. Даже с этими сдвигами должно быть гораздо оптимальнее чем компилится. Не в них главная проблема. Сейчас пришёл и посмотрел в проект - вообще-то у меня изначально стояло -mv6740, и то что я приводил вначале - это с помощью него и скомпилено. Так что - мимо кассы. :laughing: Лучше покажите как вы этого добились "8 iterations in parallel"? У меня "ii = 4 Schedule found with 4 iterations in parallel" и длина цикла ==16тактов. Именно с -mv6740 2 LDDW и 2 STDW - я пока и не мечтаю. Если-б компилятор хотя-бы эти NOP-ы убрал....... В другой функции у меня получаются 2 LDDW в параллель, но после них стоит NOP 4, который убивает всю пользу от этих LDDW :( PS: Сейчас попробовал разные ключики: -mv6700, -mv6710, -mv6740, -mv67p - при всех кроме -mv6740 получается цикл в 4 такта, и только при -mv6740 дыра какая-то.... :01: Причём нигде кроме -mv6740 не используется SPLOOP
  3. Вечером попробую -mv6740 - но что-то не помню такой опции в компилёре.... Учту. Я сомневался, что SPINT отрабатывает насыщение, поэтому и поставил сдвиг
  4. Заинтересовала 2-я задача. ТЗ на код хотя-бы в общих чертах? И сколько платите и срок? PS: В настоящее время работаю с платой на OMAP-L137.
  5. Во! Скомпилил как у вас для C67+ и сразу получил 4 такта внутри kernel loop (у вас 2 такта как я понимаю) - очень похоже на Ваш результат. Вернул обратно на C674x - всё вернулось к старому моему результату - похоже не даёт оптимизить тип процессора :crying: Все отладки у меня выключены. Вот что получается: ;*----------------------------------------------------------------------------* ;* SOFTWARE PIPELINE INFORMATION ;* ;* Loop found in file : DSPF_fltoq31.c ;* Loop source line : 112 ;* Loop opening brace source line : 112 ;* Loop closing brace source line : 129 ;* Known Minimum Trip Count : 1 ;* Known Max Trip Count Factor : 1 ;* Loop Carried Dependency Bound(^) : 0 ;* Unpartitioned Resource Bound : 2 ;* Partitioned Resource Bound(*) : 4 ;* Resource Partition: ;* A-side B-side ;* .L units 2 2 ;* .S units 2 2 ;* .D units 2 2 ;* .M units 2 2 ;* .X cross paths 0 2 ;* .T address paths 4* 4* ;* Long read paths 0 0 ;* Long write paths 0 0 ;* Logical ops (.LS) 0 0 (.L or .S unit) ;* Addition ops (.LSD) 0 0 (.L or .S or .D unit) ;* Bound(.L .S .LS) 2 2 ;* Bound(.L .S .D .LS .LSD) 2 2 ;* ;* Searching for software pipeline schedule at ... ;* ii = 4 Schedule found with 5 iterations in parallel ;* Done ;* ;* Loop will be splooped ;* Collapsed epilog stages : 0 ;* Collapsed prolog stages : 0 ;* Minimum required memory pad : 0 bytes ;* ;* Minimum safe trip count : 1 ;*----------------------------------------------------------------------------* Ключик этот у меня включён и Partitioned Resource Bound почти ка у вас == 4, а толку нет :(
  6. Похоже дело было не в затирании памяти. Сейчас ещё проверил - все работает. Наверно висло не из-за этого, а когда я заглянул в листинг - мне показалось странным такое поведение указателя 'y'. Спасибо SAURIS GmbH разъяснил про SPMASK :rolleyes: Кстати эту функцию я получил из такой: void DSPF_fltoq31(const float* restrict x, int * restrict y, int n) { int fadcr_store; _nassert(n > 0); _nassert(n % 2 == 0); fadcr_store = FADCR; //preserve the FADCR value FADCR = _set(FADCR, 9, 10); //set FADCR bits to switch to ROUND TOWARD NEGATIVE INF FADCR = _set(FADCR, 25, 26); //set mode for both L units #pragma MUST_ITERATE(1, , ) for (x += n - 1; --n >= 0; ) *y++ = _sshl(_spint(*x-- * 0x800000), 8); FADCR = fadcr_store; //restore the FADCR value } Ожидал, что если сделать групповую обработку по 4 сэмпла, это должно ускорить. По листингу вижу, что вроде тактов стало меньше, но почему-то по измерениям загрузка процессора как была 8.8% так и осталась Кстати - попробовал interrupt threshold в опциях проекта (==3000) и вообще попробовал перед функцией поставить: #pragma FUNC_INTERRUPT_THRESHOLD(-1); запретив прерывания на время выполнения функции - на генерируемый компилятором листинг это не оказывает никакого влияния. Похоже всё-таки придётся изучать асм для этого процессора. Насколько я понимаю глядя на получающийся после оптимизатора код - он очень неэффективный, столько NOP-ов... Вот это забавная штука... Да уж - в 5502 всё было по другому - наставил-бы stall-ов кроме того, что в первой команде был-бы конфликт ресурсов. Значит здесь неучёт времени выполнения (или фазы выполнения?) команд ведёт к неверной работе кода, в то время как в 5502 это вело-бы просто к лишним stall-ам.
  7. Вон оно что... Про SPMASK не читал... я собсно не знаю асма для этого ядра, так - навскидку смотрю листинг B) Здесь асм что-то сложный похоже... в C5502 был гораздо проще - там я всё целиком на нём писал ;) Надо прочитать про SPMASK. Обработчики прерывания здесь в этом ядре не сохраняют состояние аппаратных циклов и на время вызова функций DSPLIB надо запрещать прерывания? Интересно - а как тогда весь остальной код работает? Написал большой объём кода на это ядро (без использования DSPLIB и restrict) и всё прекрасно работало с множеством прерываний. С оптимизацией.
  8. С декрементированием. Посмотрите внимательнее на указанные строки листинга. Точно хочу - в буфере входных данных данные расположены в обратном порядке, а функции DSPLIB (для которых готовит данные указанная функция) требуют прямого порядка.
  9. Имеем CC3.3 + C6000 Code Generation Tools v6.1.21. Компилим с таргет = -mv6740. Функция: void DSPF_fltoq31(const float* restrict x, int * restrict y, int n) { int i0, i1, fadcr_store; float t00, t01, t10, t11; _nassert(n > 0); _nassert(n % 2 == 0); fadcr_store = FADCR; //preserve the FADCR value FADCR = _set(FADCR, 9, 10); //set FADCR bits to switch to ROUND TOWARD NEGATIVE INF FADCR = _set(FADCR, 25, 26); //set mode for both L units #pragma MUST_ITERATE(1, , ) for (; (n -= 2) >= 0; ) { t00 = x[n]; t01 = x[n + 1]; t10 = t00 * 0x800000; //multiply by 2^23 for converting to Q23 format (this brings the number in the range -0x800000 to 0x800000) t11 = t01 * 0x800000; //multiply by 2^23 for converting to Q23 format (this brings the number in the range -0x800000 to 0x800000) i0 = _spint(t10); //use intrinsic to convert the number to integer i1 = _spint(t11); //use intrinsic to convert the number to integer *y++ = _sshl(i1, 8); //saturate the number if required *y++ = _sshl(i0, 8); //saturate the number if required } FADCR = fadcr_store; //restore the FADCR value } Как видно - результат выполнения пишется в 'y' с инкрементированием. Но после компиляции смотрим в листинг и видим, что компилятор построил цикл с декрементированием 'y' !!! :crying: (обратите внимание на строки: 263, 268, 269, 277, 278) ... 241 00000090 0ce6 SPLOOP 2 ;16 ; (P) 242 00000092 9de1 || SUB .L2X A3,4,B6 243 00000094 018f0058 || SUB .L1 A3,8,A3 244 245 ;** --------------------------------------------------------------------------* 246 00000098 $C$L4: ; PIPED LOOP KERNEL 247 00000098 $C$DW$L$_DSPF_fltoq31__FPCfPii$8$B: 248 249 00000098 030c5465 LDW .D1T1 *A3--(8),A6 ; |116| (P) <0,0> 250 000000a0 041854e6 || LDW .D2T2 *B6--(8),B8 ; |118| (P) <0,0> 251 252 000000a4 00008000 NOP 5 253 254 000000a8 02990e01 MPYSP .M1 A8,A6,A5 ; |116| (P) <0,6> 255 000000ac 03a11e02 || MPYSP .M2X A8,B8,B7 ; |118| (P) <0,6> 256 257 000000b0 00004000 NOP 3 258 259 000000b4 03940159 SPINT .L1 A5,A7 ; |116| (P) <0,10> 260 000000b8 029c015a || SPINT .L2 B7,B5 ; |118| (P) <0,10> 261 262 000000bc 000b0001 SPMASK L2 263 000000c0 052b005a || SUB .L2 B10,8,B10 264 265 000000c4 0c6e NOP 1 266 267 000000c6 2f66 SPMASK S1,S2 268 000000c8 022901a3 || ADD .S2 8,B10,B4 269 000000cc 022991a0 || ADD .S1X 12,B10,A4 270 271 000000d0 029d08a1 SSHL .S1 A7,8,A5 ; |119| <0,14> 272 000000d4 0ec3 || SSHL .S2 B5,8,B5 ; |118| <0,14> 273 274 .dwpsn file "DSPF_fltoq31.c",line 120,column 0,is_stmt 275 276 000000d6 dc67 SPKERNEL 7,0 277 000000d8 2c54 || STW .D1T1 A5,*A4++(8) ; |119| <0,15> 278 000000da 3c55 || STW .D2T2 B5,*B4++(8) ; |118| <0,15> ... Естественно, что функция не работает - затирает чужую память. Если убрать модификатор 'restrict' для 'x' и 'y' всё начинает работать, но скорость совсем не та - не строится аппаратного цикла SPLOOP насколько я понимаю. Если делать обработку за один проход по одному сэмплу (одна операция *y++) - тоже всё нормально компилится и 'y' в листинге инкрементируется. Кто-нить сталкивался? Или я чего-то недогоняю? Или в CodeTools v6.1.21 'restrict' кривой и, чтобы писать быструю обработку, придётся изучать асм C674x???
  10. Опять ни байта о характеристиках изображения (разрешение, цветность и т.п.) и какая скорость загрузки картинок требуется.... Можно добавить на каждый монитор кнопку типа "Показать всем", по которой ваша картинка показывается на всех других мониторах и кнопку "выключить изображение" для скрытия. Это упростит механику - не нужна будет поворотность экранов.
  11. купить evalboard на планируемый проц для группы 2.
  12. Игра на 3-дюймовых экранах? Да ещё поворотных и встроенных в деревянную поверхность? Странная какая-то игра.... ;) PS: Нет требований по разрешению и скорости обновления картинки. А так - берём 8 любых одинаковых отладочных плат с ЖК-экранчиками, пишем ПО принимающее картинку по некоему протоколу с RS232(RS485) или Ethernet (в зависимости от требований скорости) (обычно и RS232 и Ethernet имеются на отладочных платах), прописываем каждому девайсу свой адрес, соединяем провода напрямую (RS485) или через свич (Ethernet), развешиваем девайсы по деревянному помещению и заливаем на них картинки. Если необходима синхронность смены картинки, то в протоколе предусматриваем команду смены изображения на экране на предварительно закачанное. Так что - схемотехники тут ==0, только ПО. Думаю - даже студент справится :)
  13. Ну вот - это Вам прозрачный намёк - не надо использовать БИОС :)
  14. А как насчёт банков памяти в этом ядре - имеются в нём банки памяти? Насколько помню из C5502, там были 2-портовые банки памяти, которые допускали не более двух обращений к банку за такт. Соответственно - если требуется больше обращений за такт, то расположение данных в одном банке приводит к тормозам. И приходилось входные/выходные данные фильтров и таблицы коэффициентов разносить по разным банкам памяти для получения полной скорости. Сейчас работаю с ядром C674x и пока ничего не знаю про его банкинг - есть ли он здесь? Вы именно исходник DSP_fft32 взяли? Или скомпилённую библиотеку подключили? Если первое - возможно у вас эта функция скомпилялась неоптимально. Попробуйте библиотечную. Я использую второй вариант.
  15. Ну эт Вы зря... На 300 - есть и в 10 раз больше есть ;) см. например: http://www.toshiba-components.com/microcon...er/TMPM320.html причём - в LQFP
  16. Я работаю с LPC1778. У меня периодически (наверно после того как зашью что-нить "не то") перестаёт с ним работать JTAG. Лечится только полным стиранием флеш FlashMagic-ом через UART0. При помощи только JTAG решить проблему никак не удаётся. Возможно у Вас, что-то подобное. Возможно можно попробовать перевести его в режим ISP при включении питания, а потом - JTAG-ом получится прошить. Да - версия подтвердилась - замкнул ногу 2.10 (вход в режим ISP) на GND при вкл. питания - после этого JTAG заработал и позволил прошить флеш. Значит именно в этом и было дело - мусор во флешке при вкл. питания может приводить к неработе JTAG.
  17. А зачем так сложно (DMA и т.п.)? "Пара байт" вполне себе влезет в фифо UART без доп. затрат микроампер на включённое DMA
  18. Можно приоткрыть завесу тайны по данным 2-м пунктам?
  19. Во-втором случае будет простаивать как минимум в 2 раза большее кол-во памяти. Все кучефилы почему-то забывают об элементарной вещи, которая сводит на нет все +-ы кучи в embedded: если к примеру 2 потока используют периодически каких-то 2 блока памяти и зависимость во времени этих использований невозможно детерминировать и возможны моменты одновременного использования (т.е. - невозможно поместить эти 2 блока в union static), то они совершенно забывают, что если выделять эти блоки на куче, то тоже будут моменты одновременного использования, соответственно - объём памяти в куче должен быть равен не менее чем сумме размеров блоков (а в реальности - более из-за заголовков). Поэтому в типичном эмбеддед-приложении где нет запускаемых пользователем задач (которым при нехватке памяти можно отказать в запуске) или если нет таких потоков, выполнение которых можно остановить без ущерба функционированию системе при нехватке памяти, использование кучи не приводит к уменьшению требований по памяти, а наоборот - увеличивает требования к памяти + приводит к проблемам фрагментации. Поэтому обычное static-размещение + union для использований неперекрывающихся по времени, однозначно рулит. Поймите-же эту простую мысль, кучефилы, и творения ваши станут чуть менее глючными!!! :)
  20. Проще наложить одно единственное обязательство - не использовать кучу.
  21. TiWi-R2 (WL1271)

    Если-б вы просто тупо пощёлкали ссылки дальше, то поняли-бы что инфы реально нет ;) Юзермануал на WL1271 дают под NDA.
  22. Смотрим на название форума :) В ARM все 8-/16-/32-разрядные команды сохранения атомарны. Ну если только преднамеренно не разместить их невыровненными...
  23. Только когда пишет один процессор, а читает - другой, тут запрет прерываний не спасёт ;)
×
×
  • Создать...