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

repstosw

Участник
  • Постов

    2 650
  • Зарегистрирован

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

    2

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


  1. У Блекфина система команд такая, что особо не разбежишься. Всё очень строго, и конвеер там допускает инструкции в строго определенной последовательности. Строковых блочных команд нет вроде. Смотрел внимательно тут: 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;"); \
  2. По-разному пробовал: //#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 бита подряд за одно чтение? Есть ли такая фишка в Блекфинах? :rolleyes: :rolleyes: :rolleyes: У Intel-ловских процессоров есть подобное с mmx- и xmm- регистрами: 8 байт за раз переслать можно аналогично!
  3. Согласен, иначе следующие PIXEL при if()else... не попадут под условие. Попробую вернуть внутренний цикл и посмотреть что сделает компилятор(асм- листинг). Пробовал процедуру отрисовки скопировать в 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 МБайт.
  4. Быстро, в смысле уменьшить время перекидывания буфера на экран. Перерисовка экрана полная. Посмотрел листинг функции на ассемблере, мой опыт не позвояет сказать насколько оптимально делает VDSP++, листинг приложил. Знающих в ассебмлере, прошу глянуть листинг - оцените насколько неоптимально или оптимально сделал компилятор свою работу? Если же слабые места будут, то буду копать ассемблер BF. asm.txt Это два пиксела по 16 бит каждый.
  5. Здравствуйте. Использую ADSP BF533 + SDRAM + OLED Display (подключен к EBIU 16 бит). Программа загружена в SDRAM, кэширование включено: для данных и программ, политика write back. Дисплей не прокеширован. Периодически нужно отрисовывать кадр на дисплей, как можно быстрее. Видеопамять дисплея - 16 бит на пиксел, адрес автоматически увеличивается на +1 пиксел после отрисовки точки. Есть буфер в котором строистя изображение - источник. Кодировка цветов через палитру. Приемником выступает сам дисплей. Палитру засунул в L1_DATA_B, чтобы ускорить доступ к ней (попиксельно идет обращение). Буфер источника находится в SDRAM (кеширована). За один присест сразу рисую 2 пиксела по 16 бит, по сути формирую 32-битное обращение к памяти дисплея: #define OLED_Data_32 (*(volatile u32*) 0x20010000) Хотя он подключен к 16-битной шине. Фрагмент кода: //u8, u16, u32 - char, short и long соответственно 1 2 4 байта UINT16* palette_16bit_lookup=(UINT16*)0xFF900000; //L1_DATA_B 16KB Тут палитра #define SRC_PITCH 544 /* Ширина источника */ #define DST_HEIGHT 224 /* Высота приемника */ #define SCR_WIDTH 320 /* Ширина дисплея */ #define SCR_HEIGHT 240 /* Высота дисплея */ #define OLED_Data_32 (*(volatile u32*) 0x20010000) /* Это регистр данных дисплея с автоинкрементом адреса, подключен к EBIU Blackfin - разрядность 16 бит */ #define PIXEL OLED_Data_32=(palette_16bit_lookup[src[1]]<<16)|palette_16bit_lookup[src[0]];src+=2; /* выводим сразу 2 пиксела(по 16 bit) на дисплей, цвет берем из палитры */ #define PIXELLAST OLED_Data_32=(palette_16bit_lookup[src[1]]<<16)|palette_16bit_lookup[src[0]];src+=(SRC_PITCH-SCR_WIDTH+2); /* последние 2 пиксела */ void Draw_Window(struct BITMAP *bitmap) //Отправка буфера на дисплей { register u16* src=(u16*)(((u32)bitmap->base)+17536+64); //Стартовый адрес источника register u32 y=DST_HEIGHT; OLED_Rectangle(0,(SCR_HEIGHT-DST_HEIGHT)>>1,SCR_WIDTH-1,((SCR_HEIGHT+DST_HEIGHT)>>1)-1); //Задаёт прямоугольную область 320x224 по центру дисплея (сам дисплей 320x240) while(y--) //цикл по Y, цикл по X развернут на 320 точек (160 слов) { PIXEL /* 159 раз */ PIXEL PIXEL /* ... */ PIXEL PIXEL PIXELLAST /* 160-й раз */ } } Цикл по X развернут макросами для ускорения. Компилировал это дело в Visual DSP++ 5.1.2 - пробовал такую оптимизацию: Speed 100, Interprocedural optimization, Frame-pointer optimization. Код работает как нужно , но подозреваю, что можно сделать быстрее! Дает ли прирост скорости 32-битное обращение к регистру данных дисплея, когда он подключен к 16-битной шине? Фактически это 2 операции подряд по 16 бит с увеличением адреса (не используются). Как можно сделать ещё быстрее? Рассмотрю любые способы: от изменения алгоритма, до системного управления процессором (кеширование, выравнивание). Пробовал изменить тайминги шины EBIU, ничего не меняется. Как можно пере-инициализировать контроллер асинхронной шины, когда он уже работает?
×
×
  • Создать...