реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> ARM Ассемблер, программирование-искусство?
MALLOY2
сообщение Mar 9 2009, 12:40
Сообщение #16


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



расчет CRC32, ЦФ, свертка, FFT, практически все матиметические циклы будут на асме работать быстрее! Вопрос вы будите писать их на асм или возьмете мощнее процессор ?
Go to the top of the page
 
+Quote Post
kons
сообщение Mar 9 2009, 12:55
Сообщение #17


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 28-09-05
Пользователь №: 9 035



to KRS.
Вы правы, кол-во обращений к данным не уменьшает, но (для ARM7TDMI, у Cortex и особенно ARM9 разница не столь существенна) LDR - 3 такта/слово, LDMIA - 2+1*кол-во слов. Т.е. при загрузке, скажем, 8 регистров LDRx8 = 24 такта, LDMIA - 10 тактов. Да, забыл сказать - это при выполнении из RAM. При выполнении из флэша на AT91SAM7 добавьте к каждому LDR еще по такту - флеш медленнее, однако.

Простенький пример - цикл вычисления FIR. Данные берутся из циркулярного буфера (DL_PTR, DL_BASE, DL_SIZE). Обрабатываются 4 отвода за раз. Напишите на c, скомпилируйте, посчитайте такты, сравните. А стоит или не стоит это делать на ASM - зависит от потребной частоты вычисления и длины фильтра. В моем случае (Fд=48 кГц, L=20 отводов, и кроме этого еще куча дел) - стоило однозначно. Была бы Fд 8 кГц - не стал бы заморачиваться. Что же касается реакции на прерывания - на то DMA есть.

FIR_DELAY_LOOP MACRO
LOCAL FDL_LP
FDL_LP: LDMDB DL_PTR!,{R_SMP3-R_SMP0} ;8
CMP DL_PTR,DL_BASE
ADDLS DL_PTR,DL_PTR,DL_SIZE
LDMIA SUFF_PTR!,{R_SUFF0-R_SUFF3} ;6
MLA R_ACC,R_SUFF0,R_SMP0,R_ACC ;16
MLA R_ACC,R_SUFF1,R_SMP1,R_ACC
MLA R_ACC,R_SUFF2,R_SMP2,R_ACC
MLA R_ACC,R_SUFF3,R_SMP3,R_ACC
SUBS SUFF_CNT,SUFF_CNT,#4 ;4
BNE FDL_LP
ENDM

P.S. А как тут код нормальный вставлять? Что с цитатой, что без - все одно каша...

to Pasha:
Цитата
Это квадратные советы. Они не учитывают задачи портирования, коих большинство, когда об алгоритме уже известно почти все, надо чтобы оно красиво влезло и не мешало жить наращиваемой функциональности. В таких случаях я лично начинаю с проверки и оптимизации именно узких мест.

+500. Особенно для DSP, и особенно на этапе выбора процессора.
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Mar 9 2009, 13:37
Сообщение #18


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(MALLOY2 @ Mar 9 2009, 07:40) *
расчет CRC32, ЦФ, свертка, FFT, практически все матиметические циклы будут на асме работать быстрее! Вопрос вы будите писать их на асм или возьмете мощнее процессор ?


Мощнее процессор решение тупое но часто приемлимое. Иногда, к счастью нет -- иначе бы Visual Basic и в embedded programming пробрался бы smile.gif Когда стоит задача добиться минимального потребления тока оптимизация на асм. очень помогает, ибо каждая лишняя инструкця цикла это сколько-то лишних nA. (При условии что программа в основном спит, и изредка включается чтобы обработать данные).
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 9 2009, 13:39
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(kons @ Mar 9 2009, 15:55) *
P.S. А как тут код нормальный вставлять? Что с цитатой, что без - все одно каша...

Теги [сode] и [сodebox].
Go to the top of the page
 
+Quote Post
KRS
сообщение Mar 9 2009, 14:28
Сообщение #20


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(kons @ Mar 9 2009, 15:55) *
Простенький пример - цикл вычисления FIR. Данные берутся из циркулярного буфера (DL_PTR, DL_BASE, DL_SIZE)...

конечно компилер так не сможет скомпилировать, потому что у вас куча допущений: например длина циклического буфера кратна 4 словам! и соотвественно STUFF_CNT тоже кратно 4. Если вы сумеете объяснить это компилятору...
По поводу раскрутки циклов IAR это делать умеет простой пример:
Код
unsigned test(unsigned *dl, unsigned *suff)
{
    unsigned r;
    unsigned cnt;
    r = 0;
    cnt = 16;
    do {
        r += (*(dl++)) * (*(suff++));
    }while(--cnt);
    return r;
}

получаем листинг
Код
      1          unsigned test(unsigned *dl, unsigned *suff)
      2          {
   \                     test:
   \   00000000   00402DE9           PUSH     {LR}
   \   00000004   04D04DE2           SUB      SP,SP,#+4
      3              unsigned r;
      4              unsigned cnt;
      5              r = 0;
   \   00000008   0020A0E3           MOV      R2,#+0
      6              cnt = 16;
   \   0000000C   0430A0E3           MOV      R3,#+4
      7              do {
      8                  r += (*(dl++)) * (*(suff++));
   \                     ??test_0:
   \   00000010   04C090E4           LDR      R12,[R0], #+4
   \   00000014   04E091E4           LDR      LR,[R1], #+4
   \   00000018   9E2C22E0           MLA      R2,LR,R12,R2
      9              }while(--cnt);
   \   0000001C   04C090E4           LDR      R12,[R0], #+4
   \   00000020   04E091E4           LDR      LR,[R1], #+4
   \   00000024   9E2C22E0           MLA      R2,LR,R12,R2
   \   00000028   04C090E4           LDR      R12,[R0], #+4
   \   0000002C   04E091E4           LDR      LR,[R1], #+4
   \   00000030   9E2C22E0           MLA      R2,LR,R12,R2
   \   00000034   04C090E4           LDR      R12,[R0], #+4
   \   00000038   04E091E4           LDR      LR,[R1], #+4
   \   0000003C   9E2C22E0           MLA      R2,LR,R12,R2
   \   00000040   013053E2           SUBS     R3,R3,#+1
   \   00000044   F1FFFF1A           BNE      ??test_0
     10              return r;
   \   00000048   0200A0E1           MOV      R0,R2
   \   0000004C   04D08DE2           ADD      SP,SP,#+4       ;; stack cleaning
   \   00000050   0080BDE8           POP      {PC}            ;; return
     11          }

да LDMIA конечно не задействован, но раскрутка на лицо.

А если взять такую функцию (раскрутить цикл вручную)
Код
unsigned test(unsigned *dl, unsigned *suff, unsigned cnt)
{
    unsigned r;
    r = 0;
    do {
        unsigned d1,d2,d3,d4;
        unsigned s1,s2,s3,s4;

        d1 =  *(dl++);
        d2 =  *(dl++);
        d3 =  *(dl++);
        d4 =  *(dl++);

        s1 = *(suff++);
        s2 = *(suff++);
        s3 = *(suff++);
        s4 = *(suff++);

        r += s1*d1 + s2*d2 + s3*d3 + s4*d4;
    }while(cnt-=4);
    return r;
}

и взять компилер помощнее ( RVCT 4.0)
то получим такой asm
Код
; generated by ARM C/C++ Compiler, RVCT4.0 [Build 471]
; commandline armcc [-S -O3 -Otime test.c]
        ARM
        REQUIRE8
        PRESERVE8

        AREA ||.text||, CODE, READONLY, ALIGN=2

test PROC
        PUSH     {r4-r10}
        MOV      r3,#0
|L1.8|
        LDR      r12,[r0],#4
        LDM      r1!,{r7,r8,r10}
        LDM      r0!,{r4-r6}
        MUL      r12,r7,r12
        MUL      r5,r10,r5
        MLA      r12,r8,r4,r12
        LDR      r9,[r1],#4
        SUBS     r2,r2,#4
        MLA      r4,r9,r6,r5
        ADD      r12,r12,r4
        ADD      r3,r3,r12
        BNE      |L1.8|
        POP      {r4-r10}
        MOV      r0,r3
        BX       lr
        ENDP

так что умеют компиляторы и LDMIA использовать smile.gif

я конечно не утверждаю что надо без asm обходится! действительно многие вещи приходится писать на нем, но часто в силу того что на С не объснить компилеру некоторые ньюансы. Но не стоит недооценивать современные компиляторы.
Go to the top of the page
 
+Quote Post
kons
сообщение Mar 9 2009, 15:36
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 28-09-05
Пользователь №: 9 035



Да, хорошая штука RVCT. Мой IAR так не умеет - проверял. Однако такой код на c выходит длиннее ассемблерного. А для того, чтобы написать его и заценить понятливость компилятора, все равно надо знать asm...
Go to the top of the page
 
+Quote Post
KRS
сообщение Mar 9 2009, 16:22
Сообщение #22


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(kons @ Mar 9 2009, 18:36) *
А для того, чтобы написать его и заценить понятливость компилятора, все равно надо знать asm...

C этим не поспоришь!
Еще при этом можно узнать некоторые особенности компилятора, например если заменить строчку
Код
r += s1*d1 + s2*d2 + s3*d3 + s4*d4;

на
Код
        r += s1*d1;
        r += s2*d2;
        r += s3*d3;
        r += s4*d4;

то получим в RVCT слегка другой листинг
Код
        LDR      r12,[r0],#4
        LDM      r1!,{r7,r8,r10}
        MLA      r3,r7,r12,r3
        LDM      r0!,{r4-r6}
        MLA      r3,r8,r4,r3
        MLA      r3,r10,r5,r3
        LDR      r9,[r1],#4
        SUBS     r2,r2,#4
        MLA      r3,r9,r6,r3
        BNE      |L1.8|

тут видно что для RVCT подобные циклы лучше разворачивать на 3 операции ( 6 регистров он может выделить), а не на 4
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th August 2025 - 16:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01465 секунд с 7
ELECTRONIX ©2004-2016