Jump to content

    

__inline__

Участник
  • Content Count

    743
  • Joined

  • Last visited

Everything posted by __inline__


  1. Цитатазаглянул сейчас в тот свой код ЧМ-модулятора, пересчитал - он занимал процессорного времени менее 0.5%. И это ещё не самый быстрый алгоритм (считаю синус полиномом), можно гораздо быстрее. Непонятно какие могут быть трудности с каким-то "FM-синтезатором" звуковой частоты ЦитатаНа CPU автора (даже если предположить, что он генерит 3 синусоидальных сигнала и смешивает их потом, а не тупо - 3 меандра biggrin.gif ) даже в случае 3 синусоид и частоты квантования 48кГц, загрузка CPU этим синтезатором должна быть менее 1%. Так и хочется натянуть свой опыт, да? Не выйдёт. Не мешайте говно с мёдом....... Для начала советую поразмыслить над тем, как эмуляция вашего ЧМ-модулятора относится к: 1) Capcom System QSound™ 2) Yamaha YM2151 3) OKI6295 Вы хотя бы один из этих чипов эмулировали ? Более на дебаты теоретиков не реагирую. ------------------ А теперь вопросы: 1) Насколько тормозной тип double для BlackFin ? Имеет ли смысл его заменить float ? 2) Каким образом можно изменить параметры растактовки шины EBIU для асинхронного банка, когда он был инициализирован ранее? Тоесть переинициализировать. После того как EBIU запущен, изменить параметры перезаписью в региcтры: EBIU_AMBCTL0 EBIU_AMBCTL1 EBIU_AMGCTL не получается!
  2. Если критические участки в программе переписывать на Ассемблере (эмуляция процессоров, эмуляция графики / звука), то производительность должна вырасти. Это выходит за рамки моей задачи, так как было нужно портировать эмулятор (автором которого я НЕ являюсь) на устройство с ADSP BF533. В целом результатом доволен, быстродействие вышло таким: 45 - 55 FPS при эмуляции CPS1 30 - 40 FPS при эмуляции CPS2. При этом показывается каждый кадр, звуковой поток не рвётся (темп плавно понижается). Система CPS слишком наворочена, так как графика/звук у неё заточены под игры(быстрые). И не надо сравнивать какой-то допотопный КР580ВМ80 в связке с убогой графикой (Спектрум небось? ) Ну и вдогонку: телефон с процессором ARM9 800 МГц воспроизводит данный эмулятор хуже (не мой порт), и КПК на 300 МГц ещё хуже! Замерял количество полных отрисовок экрана за 1 секунду (Буфер 320x224x2 из SDRAM + конвертация 16-битной палитры + вывод на дисплей) - 188 раз. Мерял этим: Кодstatic __inline__ enable_cycles(void) { __asm__ __volatile__ ("R2=SYSCFG;"); __asm__ __volatile__ ("BITSET(R2,1);"); __asm__ __volatile__ ("SYSCFG=R2;"); } static __inline__ disable_cycles(void) { __asm__ __volatile__ ("R2=SYSCFG;"); __asm__ __volatile__ ("BITCLR(R2,1);"); __asm__ __volatile__ ("SYSCFG=R2;"); } static __inline__ start_cycles(void) { __asm__ __volatile__ ("R2=0;"); __asm__ __volatile__ ("CYCLES=R2;"); __asm__ __volatile__ ("CYCLES2=R2;"); } static __inline__ u64 get_cycles(void) { u32 t0,t1; __asm__ __volatile__ ("%0=cycles;%1=cycles2;":"=d"(t0),"=d"(t1)); return t0|((u64)t1<<32); } Цитата(_pv @ Sep 8 2017, 23:13) да как-то всё равно не очень-то быстро. Z80 на АВРах даже как-то эмулируется, 68к с его 5мипсами не особо сложнее должно быть. а тут целый блэкфин на 550МГц. Это типа троллинг? Полный перечень того что делается: Цитата// эмуляция процессоров Z80, M68020 // эмуляция видео-подсистемы (4 графических слоя) // эмуляция звуковой системы (FM синтезатор + ADPCM + Wav sound*4 канала) // эмуляция системы ввода // эмуляция памяти //эмуляция ROM-set-а // отрисовка на дисплей // вывод звука // считывание клавиш
  3. Цитата(jcxz @ Sep 8 2017, 19:01) И сколько получилось? 40+15 FPS? И это по 16-битной шине?? Это всё равно очень медленно. Это FPS всего эмулятора, а не экранный FPS: Кодwhile(!quit) { // эмуляция процессоров Z80, M68020 // эмуляция видео-подсистемы (4 графических слоя) // эмуляция звуковой системы (FM синтезатор + ADPCM + Wav sound*4 канала) // эмуляция системы ввода // эмуляция памяти //эмуляция ROM-set-а // отрисовка на дисплей // вывод звука // считывание клавиш } Вот это всё ВМЕСТЕ - 55 FPS !
  4. Сделал DMA по прерываниям. Буфер - 320 пикселов (одна строка) 640 байт в L1, уже сконверченная палитрой(тоже в L1). Даём DMA команду на отрисовку строки, а сами делаем дальше остальные вещи. Прерывание по окончанию пересылки строки снова запускает DMA для новой строки. И так пока экран не отрисуется весь. Код что ниже - рабочий, удаось поднять общую скорость (отрисовка экрана + вся программа) на 15 FPS !!! Получается, что отрисовка экрана и работа процессора немного распараллелились. Макросы использую, потому что 100% гарантия что с-инлайнится. Код#define SRC_PITCH  544 #define DST_HEIGHT 224 #define SCR_WIDTH  320 #define SCR_HEIGHT 240 //0xFF800000..0xFF803FFF //L1_DATA_A #define NB (SCR_WIDTH<<1) #define L1_MEMORY 0xFF804000 #define L1_BUF (L1_MEMORY-NB) #define DMA_INIT                         \ {                                        \ *pMDMA_S1_PERIPHERAL_MAP=0x0040;        \ *pMDMA_S1_START_ADDR=(void*)L1_BUF;     \ *pMDMA_S1_X_COUNT=(NB>>1);              \ *pMDMA_S1_X_MODIFY=2;                   \ *pMDMA_S1_Y_COUNT=1;                    \ *pMDMA_S1_Y_MODIFY=0;                   \ *pMDMA_D1_PERIPHERAL_MAP=0x0040;        \ *pMDMA_D1_START_ADDR=(void*)&OLED_Data; \ *pMDMA_D1_X_COUNT=(NB>>1);              \ *pMDMA_D1_X_MODIFY=0;                   \ *pMDMA_D1_Y_COUNT=1;                    \ *pMDMA_D1_Y_MODIFY=0;                   \ }                                        \ #define DMA_START                            \ {                                            \ *pMDMA_S1_CONFIG=WDSIZE_16|DMAEN;           \ *pMDMA_D1_CONFIG=WDSIZE_16|WNR|DMAEN|DI_EN; \ }                                            \ #define DMA_STOP                       \ {                                      \ *pMDMA_S1_CONFIG=0;                   \ *pMDMA_D1_CONFIG=0;                   \ }                                      \ extern struct mame_display current_display; u16* src; EX_INTERRUPT_HANDLER(DMA_ISR) { static u16 y=DST_HEIGHT; *pMDMA_D1_IRQ_STATUS=1; y--; if(y) {   register u16* buf=(u16*)L1_BUF;   register u16 i;   for(i=0;i<(NB>>1);i++)*buf++=palette_16bit_lookup[*src++];   src+=(SRC_PITCH-SCR_WIDTH);   DMA_START } else {   y=DST_HEIGHT;   DMA_STOP } } void DMA_Init_Interrupt(void) { *pSIC_IMASK&=0xFFBFFFFF;                       //Disable MDMA1 interrupt *pSIC_IAR2=(*pSIC_IAR2&0xF0FFFFFF)|0x06000000; register_handler(ik_ivg13,DMA_ISR); *pSIC_IMASK|=0x00400000;                       //Enable MDMA1 interrupt } int win_init_window(void) {         // disable win_old_scanlines if a win_blit_effect is active         if (win_blit_effect != 0)                 win_old_scanlines = 0; DMA_Init_Interrupt(); DMA_INIT OLED_Clear(0x0000); return 0; } void dib_draw_window_DMA(void) { OLED_Rectangle(0,(SCR_HEIGHT-DST_HEIGHT)>>1,SCR_WIDTH-1,((SCR_HEIGHT+DST_HEIGHT)>>1)-1); src=(u16*)(((u32)current_display.game_bitmap->base)+17536+64); register u16* buf=(u16*)L1_BUF; register u16 i; for(i=0;i<(NB>>1);i++)*buf++=palette_16bit_lookup[*src++]; src+=(SRC_PITCH-SCR_WIDTH); DMA_START }
  5. Цитата(_pv @ Sep 6 2017, 16:05) 0) завели два буфера по 64 байта. 1)настроили ДМА, чтобы забрать 32 точки из сдрама(ну или забрали руками, тут без разницы) в буфер №1 2)курим бамбук, так как без шины заняться нечем. 3)по получении данных отправили предыдущий буфер№2 из 32 точек на отрисовку через дма 4)пока дма перекладывает данные в дисплей, обрабатываем только что полученные данные в буфере№1. 5)как только старые данные ушли (обработка вроде бы должна закончиться гораздо быстрее у дисплею надо 21ССLK на пиксель, а процессор за 3-5 управиться должен из внутренней памяти), поменяли местами указатели на буферы GOTO 1 Всё сделал как написали, работает исправно, но прироста скорости всёравно нет. Пробовал убрать dma_wait, скорость повышается, но экран отрисовывается на 1/4 и весь трясётся (что и понятно почему). Попробую не ждать, а в обработчик прерывания засунуть вывод на дисплей через DMA. Рабочий код ниже: Код#ifndef __DMA_H__ #define __DMA_H__ //0xFF800000..0xFF803FFF //L1_DATA_A #define NB 32 #define buf0 (0xFF803FC0-(NB<<1)) #define buf1 (0xFF803FE0- NB    ) #define DMA_INIT                         \ {                                        \ *pMDMA_S1_PERIPHERAL_MAP=0x0040;        \ *pMDMA_S1_X_COUNT=(NB>>1);              \ *pMDMA_S1_X_MODIFY=2;                   \ *pMDMA_S1_Y_COUNT=1;                    \ *pMDMA_S1_Y_MODIFY=0;                   \ *pMDMA_D1_PERIPHERAL_MAP=0x0040;        \ *pMDMA_D1_START_ADDR=(void*)&OLED_Data; \ *pMDMA_D1_X_COUNT=(NB>>1);              \ *pMDMA_D1_X_MODIFY=0;                   \ *pMDMA_D1_Y_COUNT=1;                    \ *pMDMA_D1_Y_MODIFY=0;                   \ }                                        \ #define DMA_SEND(buf)                  \ {                                      \ *pMDMA_S1_START_ADDR=(void*)buf;      \ *pMDMA_S1_CONFIG=WDSIZE_16|DMAEN;     \ *pMDMA_D1_CONFIG=WDSIZE_16|WNR|DMAEN; \ }                                      \ #define DMA_WAIT while(*pMDMA_D1_IRQ_STATUS&DMA_RUN); #define MEMORY_COPY(dst,src)       \ {                                  \ register u16 i;                   \ register u32* d=(u32*)dst;        \ register u32* s=(u32*)src;        \ for(i=0;i<(NB>>2);i++) *d++=*s++; \ }                                  \ #define PALETTE_CONVERT(buf)                          \ {                                                     \ register u16 i;                                      \ register u16* c=(u16*)buf;                           \ for(i=0;i<(NB>>1);i++)*c++=palette_16bit_lookup[*c]; \ }                                                     \ #endif Кодvoid dib_draw_window_DMA(void) { register u16* src=(u16*)(((u32)current_display.game_bitmap->base)+17536+64); register u16 y=DST_HEIGHT; while(y--) {   register u16 x=(u16)SCR_WIDTH/(u16)NB;   MEMORY_COPY(buf1,src)   PALETTE_CONVERT(buf1)   src+=(NB>>1);   while(x--)   {    MEMORY_COPY(buf0,src)    DMA_SEND(buf1)    PALETTE_CONVERT(buf0)    src+=(NB>>1);    DMA_WAIT    MEMORY_COPY(buf1,src)    DMA_SEND(buf0)    PALETTE_CONVERT(buf1)    src+=(NB>>1);    DMA_WAIT   }   src+=(SRC_PITCH-SCR_WIDTH-(NB>>1)); } }
  6. Цитата(_pv @ Sep 6 2017, 15:24) когда данные не во внешней памяти, а уже в регистре то это преобразование занимает два такта. ну и если взять в среднем, пиксель всё таки читается каждый кадр, а вот пишется думаю далеко не каждый. правда исходное разрешение наверное больше чем выходное 320х240, тогда пожалуй да, лучше конвертировать при выводе. ну у процессора-то не отберёт, там приоритет вроде как поставить можно кто главней процессор или дма если оба наружу хотят обратиться. что такое цикл эмуляции? вот есть у вас 15мс между кадрами при 60Гц, за это время надо успеть наэмулировать 15мс тактов приставки и отрисовать экран. какая разница в каком порядке. 320*240 / 26МГц = 3мс, это время в течении которого шина всё равно будет просто занята отрисовкой на экран, чтение из памяти гораздо быстрее можно не учитывать, так почему бы в эти 3мс процессору не заняться конвертированием цветов, ПАРАЛЛЕЛЬНО с выдачей, а не последовательно как сейчас. потому что ничего другого он всё равно без внешней шины делать не сможет. Весь цикл программы можно упрощенно представить так: Кодwhile(!Quit) { эмулируем... рисуем... } Если запустить DMA и отрисовывать построчно, то всеравно прийдется ждать окончания работы DMA чтобы подсунуть ему новую линию с декодированной палитрой при передаче. В момент работы ДМА, процессор всеравно будет брать индексы из SDRAM, а это снова шина. В итоге процессор и ДМА будут рвать шину по кускам.
  7. Цитата(_pv @ Sep 6 2017, 11:44) раз это память никак не экономит, делайте конверсию в цвет по палитре при записи в буфер, а не при чтении, и выводите тогда просто направив дма из внешней памяти на экран вообще без участия процессора. Там очень хитрый буфер. И он "грязный", потому что по-очереди отрисовываются несколько спрайтовых плоскостей (видеосистема Capcom PlaySystem 1/2). Если преобразовывать палитру там, то боюсь всё замедлится в число раз, равное числу плоскостей. Цитата(_pv @ Sep 6 2017, 11:44) буфер не обязательно на всю строку делать, 8-16-32 пикселя возможно уже вполне хватит чтобы успеть и данные пережевать и дма перенастроить. главное чтобы не процессор занимался перекладыванием данных из регистра/внутренней памяти наружу. Процессор к сожалению будет конвертить палитру, а DMA так же занимать шину во время транзакций. И можно будет авансом заранее сделать не более 1 цикла эмуляции, до того как экран будет полностью не отрисован, иначе пропуск кадра будет что плохо. Проверил работу процедуры. На практике вышло чуть-лучше. Но ненамного. Вот код всей процедуры - пока не вычесал, затронут только внутренний цикл. Код.section/DOUBLE32 program; .extern _current_display; .extern _palette_16bit_lookup .global _dib_draw_window_asm; _dib_draw_window_asm:     [--SP] = (P5:3);     P1.L = _current_display+4;     P1.H = _current_display+4;     P1 = [P1];     P2 = 17600;     P0 = 224;     I0 = 0;     I0.H = 8193;     P1 = [P1 + 16];     P5.L = _palette_16bit_lookup;     P5.H = _palette_16bit_lookup;     P4 = 4;     P1 = P1 + P2;     [SP + 12] = P1;     LOOP CycleYL LC1 = P0; CycleY:     LOOP_BEGIN CycleYL;     P1 = [SP + 12];     P0 = 80;     P3 = [P5];         R5=P3;     LOOP CycleXL LC0 = P0; CycleX:     LOOP_BEGIN CycleXL;                      R0=W[P1 + 2] (Z)     ;     R0=R0<<1      || R1=W[P1 ++ P4] (Z)   ;     R1=R1<<1      || R2=W[P1 + 2] (Z)     ;     R2=R2<<1      || R3=W[P1 ++ P4] (Z)   ;     P0=R3                                 ;     P0=P3+(P0<<1)                         ; //Preg read after write which requires 4 extra cycles     R0=R0+R5 (NS) || R7.L=W[P0]           ;     I1=R0                                 ;     R1=R1+R5 (NS) || R6.H=W[I1]           ; //Dagreg read after write which requires 4 extra cycles     I1=R1                                 ;     R2=R2+R5 (NS) || R6.L=W[I1]           ; //Dagreg read after write which requires 4 extra cycles     I1=R2                                 ;     R3=R3+R5 (NS) || R7.H=W[I1] || [I0]=R6; //Dagreg read after write which requires 4 extra cycles     [I0]=R7                               ;     LOOP_END CycleXL; .P35L13:     P0 = [SP + 12];     P1 = 1088;     P1 = P0 + P1;                            //Preg read after write which requires 3 extra cycles     [SP + 12] = P1;     LOOP_END CycleYL; .P35L14:     (P5:3) = [SP++];     RTS; А вот это разочаровало: //Preg read after write which requires 3 extra cycles //Dagreg read after write which requires 4 extra cycles Выходит вся оптимизация и конвеер лесом?? Пока получилось 35 - 40 FPS, в идеале должно быть 60 FPS (частота смены кадров NTSC)
  8. Цитата(_pv @ Sep 6 2017, 09:14) что толку оптимизировать эти 4 инструкции, если обращение чтение из памяти и запись в дисплей длится в несколько раз дольше 9-16 тактов. как уже не раз говорил, заставьте дма перекладывать данные, тогда обработка палитры процессором будет идти параллельно с перекладыванием данных. Процессор разогнан до 550 МГц. Шина CCLK/3=183 МГц. SDRAM работает на 183 МГц с CAS latency =2. Кеш включен (для кода и данных). Дисплей 7 тактов (setup + write + hold), в эквиваленте 183/7 = 26 МГц. Шина данных 16 бит. Цитата(_pv @ Sep 6 2017, 09:14) да и в собирании двух пикселей в одно 32х разрядное слово смысла особого нет. EBUI всё равно 16 бит. Обращение к 32 битам идет подряд как 2 раза по 16 бит, адрес+1. Но та как адресов у контроллера дисплея нет (точнее есть и висит он на самом старшем адресном бите), инкремент адреса не мешает. Это небольшой burst из двух коротких слов Сделал 14 строк ассемблера на 4 пикселя. Раньше было 11 строк на 2 пикселя. Ппришлось попарить мозг, пока вышло так (задействовал конвеер Блекфина). Пока не проверял в работе, но компилируется. Эффективность кода возросла на 36% Код#define PIXEL \ { \ __asm__ volatile ("                 R0=W[P0++] (Z);"); \ __asm__ volatile ("R0=R0<<1      || R1=W[P0++] (Z);"); \ __asm__ volatile ("R1=R1<<1      || R2=W[P0++] (Z);"); \ __asm__ volatile ("R2=R2<<1      || R3=W[P0++] (Z);"); \ __asm__ volatile ("P3=R3                        ;"); \ __asm__ volatile ("P3=P5+(P3<<1)                ;"); \ __asm__ volatile ("R0=R0+R5 (NS) || R1.H=W[P3]  ;"); \ __asm__ volatile ("I0=R0                        ;"); \ __asm__ volatile ("R1=R1+R5 (NS) || R0.L=W[I0]  ;"); \ __asm__ volatile ("I1=R1                        ;"); \ __asm__ volatile ("R2=R2+R5 (NS) || R0.H=W[I1]  ;"); \ __asm__ volatile ("I2=R2                        ;"); \ __asm__ volatile ("R3=R3+R5 (NS) || R1.L=W[I2] || [P1]=R0 ;"); \ __asm__ volatile ("  [P1]=R1    ;"); \ \ } \ Цитата(_pv @ Sep 6 2017, 09:14) если бы был дополнительный буфер во внутренней памяти, куда дма данные само подтаскивает, наверное, можно было бы ещё какой-нибудь один такт сэкономить, запараллелив запись одного пикселя с чтением следующего К сожалению объем графических данных не позволяет сделать буфер на строку во внутренней памяти + DMA. Потому что программу писал не я. Цитата(_pv @ Sep 6 2017, 09:14) ps. у вас 16ти разрядный цвет в палитре и 16ти разрядный индекс цвета, в чем смысл? Это эмуляция аркадных автоматов Capcom Play System 1/2, там палитра больше 256 цветов Вот это детище портировал на BF533: https://osdn.net/projects/mamespi/releases/2046 / https://www.zophar.net/mame/caname.html
  9. У Блекфина система команд такая, что особо не разбежишься. Всё очень строго, и конвеер там допускает инструкции в строго определенной последовательности. Строковых блочных команд нет вроде. Смотрел внимательно тут: http://microsin.net/programming/dsp/blackf...ence-part1.html http://microsin.net/programming/dsp/blackf...ence-part2.html Максимум получилось избавиться от 2 инструкций - вместо 11 строк кода имею 9: P1 - адрес src, P3 - адрес палитры, P5 - видео-регистр дисплея Код__asm__ volatile ("R0=W[P1++] (Z);"); \ __asm__ volatile ("P0=R0;"); \ __asm__ volatile ("R0=W[P1++] (Z);"); \ __asm__ volatile ("P2=R0;"); \ __asm__ volatile ("P0=P3+(P0<<1);"); \ __asm__ volatile ("P2=P3+(P2<<1);"); \ __asm__ volatile ("R1.H=W[P0];"); \ __asm__ volatile ("R1.L=W[P2];"); \ __asm__ volatile ("[P5]=R1;"); \
  10. По-разному пробовал: Код//#define PIXEL {OLED_Data_32=(palette_16bit_lookup[src[1]]<<16)|palette_16bit_lookup[src[0]];src+=2;} //#define PIXEL {OLED_Data_32=palette_16bit_lookup[*src++];OLED_Data_32=palette_16bit_lookup[*src++];} Выходит так: Код1    LOOP_BEGIN .P38L6L; 2    R0 = W[P1 + 2] (Z); 3    P0 = R0; 4    R0 = W[P1 ++ P5] (Z); 5    P2 = R0; 6    P0 = P3 + (P0<<1); 7    R0.L = W[P0]; 8    P0 = P3 + (P2<<1); 9    R1 = R0 << 16 || R0 = W[P0] (Z); 10    R0 = R1 | R0; 11    [P4] = R0; 12    LOOP_END .P38L6L; 1    LOOP_BEGIN .P38L6L; 2    R0 = W[P1++] (Z); 3    P2 = R0; 4    P2 = P4 + (P2<<1); 5    R0 = W[P2] (Z); 6    [P5] = R0; 7    R0 = W[P1++] (Z); 8    P2 = R0; 9    P2 = P4 + (P2<<1); 10    R0 = W[P2] (Z); 11    [P5] = R0; 12    LOOP_END .P38L6L; Не особо вижу разницы, да и код на внешний вид действительно неплотный. Вот это : R1 = R0 << 16 || R0 = W[P0] (Z); - параллельное выполнение команд? КодLDM R0!, {R1-R8};сорри за ARM wink.gif и получит burst-чтение SDRAM Это 8 порций по 32 бита подряд за одно чтение? Есть ли такая фишка в Блекфинах? У Intel-ловских процессоров есть подобное с mmx- и xmm- регистрами: 8 байт за раз переслать можно аналогично!
  11. Цитата(jcxz @ Sep 5 2017, 13:06) Вобщем корректно должно быть: #define PIXEL() { OLED_Data_32=(palette_16bit_lookup[src[1]]<<16)|palette_16bit_lookup[src[0]];src+=2; } /* выводим сразу 2 пиксела(по 16 bit) на дисплей, цвет берем из палитры */ Согласен, иначе следующие PIXEL при if()else... не попадут под условие. ЦитатаТакое разворачивание может наоборот навредить: например у TI в C55 если размер цикла не более 64 байт, то он помещается целиком в prefetch буфер и выполняется оттуда, гораздо быстрее (и многие stall-ы убираются при этом если они были). Если же развернуть в огромный цикл, то он не влезет и будет уже гораздо медленнее. Попробую вернуть внутренний цикл и посмотреть что сделает компилятор(асм- листинг). Пробовал процедуру отрисовки скопировать в L1 Code SRAM (64K) из SDRAM. Вот так: Кодmemcpy((void*)0xFFA00000, (const void*)Draw_Screen,0x8000); //скопировал 32 килобайта (с запасом, точный размер функции в map-файле) // 0xFFA00000 - 0xFFA0FFFF  Code SRAM (64K) При передаче управления туда - зависает. Передаю управление так: Код#define CALL(Address) (*(void(*)(void)) Address)(); //Вызов функции по её адресу CALL(0xFFA00000) Что не так? Как правильно грузить данный участок памяти кода L1 Code SRAM ? (от кеширования этот участок свободен). Есть ли #pragma в Visual DSP позволяющая сделать отдельные фуккции позиционно-независимыми? (position independent) ? Насколько оправдано размещать отдельно код процедуры отрисовки во внутренней памяти, если включено кеширование для SDRAM (I cache + D cache) ? Приложение большое - около 2 МБайт.
  12. Быстро, в смысле уменьшить время перекидывания буфера на экран. Перерисовка экрана полная. Посмотрел листинг функции на ассемблере, мой опыт не позвояет сказать насколько оптимально делает VDSP++, листинг приложил. Знающих в ассебмлере, прошу глянуть листинг - оцените насколько неоптимально или оптимально сделал компилятор свою работу? Если же слабые места будут, то буду копать ассемблер BF. [attachment=108650:asm.txt] Цитата(jcxz @ Sep 5 2017, 07:33) Вопрос про PIXEL снимается - не заметил сразу (кстати формат PIXEL у Вас неправильный). Это два пиксела по 16 бит каждый.