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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> itoa на asm, из темы "51 vs AVR"...
singlskv
сообщение Nov 13 2007, 23:19
Сообщение #1


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(mse @ Nov 3 2007, 23:51) *
itoa от =AVR= ;О) Кто быстрее?
CODE

;--------------------------------------------------------------------
; Converts an unsigned integer r5:r4 to a 5-character ASCII string [x]
; 58 program words, 73 clocks + ret
itoa:
.equ rev10k= 429497; ~= 2^32/10000

clr r2

ldi r16,low(rev10k)
ldi r17,high(rev10k)
ldi r18,byte3(rev10k)

mul r4,r16
mov r6,r1
mul r4,r17
add r6,r0
adc r1,r2
mov r7,r1
mul r4,r18
add r7,r0
adc r1,r2
mov r8,r1; r8r7r6 ~= Xlsb*429497/256, 06872B max

mul r5,r16
add r6,r0
adc r7,r1
adc r8,r2
mul r5,r17
add r7,r0
adc r8,r1
mul r5,r18
add r8,r0; r8r7 ~= int2fract(X%10000)
ldi r17,'0'
adc r1,r17; r1 = ASCII(X/10000)

st x+,r1; Tens of thousands
;--------------------------------------------------------------------
; Converts fractional 16-bit value in r5:r4 (0..9999) range
; to a 4-character ASCII string [x]
; by sequential multiplication by 10
fractoa:
ldi r16,10; Constant for multiplication by 10

sec ; Correct int2fract result to fit in 16-bit word
adc r7,r2; by incrementing it
adc r8,r2;

mul r7,r16; Multiply a 16-bit value by 10
movw r2,r0;
mul r8,r16;
add r3,r0; r3r2 ~= int2fract(X%1000)
adc r1,r17; r1 = ASCII(X/1000)
st x+,r1; Thousands

mul r2,r16; Same as above for hundreds
movw r4,r0
mul r3,r16
add r5,r0
adc r1,r17
st x+,r1

mul r4,r16; Same as above for tens
movw r2,r0
mul r5,r16
add r3,r0
adc r1,r17
st x+,r1

mul r2,r16; Same as above for units
movw r4,r0
mul r3,r16
add r5,r0
adc r1,r17
st x+,r1

ret


Ну я быстрее... smile.gif
Чиста редактируем код многоуважаемого =AVR= smile.gif
CODE

;--------------------------------------------------------------------
; Converts an unsigned integer r5:r4 to a 5-character ASCII string [x]
; 56 program words, 71 clocks + ret
itoa:
.equ rev10k= 429497; ~= 2^32/10000

clr r3

ldi r16,low(rev10k)
ldi r17,high(rev10k)
ldi r18,byte3(rev10k)

mul r4,r16
mov r6,r1
mul r4,r17
add r6,r0
adc r1,r3
mov r7,r1
mul r4,r18
add r7,r0
adc r1,r3
mov r8,r1; r8r7r6 ~= Xlsb*429497/256, 06872B max

mul r5,r16
add r6,r0
adc r7,r1
adc r8,r3
mul r5,r17
add r7,r0
adc r8,r1
mul r5,r18
add r8,r0; r8r7 ~= int2fract(X%10000)
ldi r17,'0'
adc r1,r17; r1 = ASCII(X/10000)

st x+,r1; Tens of thousands

ldi r16,10; Constant for multiplication by 10

mul r7,r16; Multiply a 16-bit value by 10
movw r2,r0
mul r8,r16
add r2,r16
adc r3,r0
adc r1,r17
st x+,r1

mul r2,r16
movw r4,r0
mul r3,r16
add r5,r0
adc r1,r17
st x+,r1

mul r4,r16
movw r2,r0
mul r5,r16
add r3,r0
adc r1,r17
st x+,r1

mul r2,r16
movw r4,r0
mul r3,r16
add r5,r0
adc r1,r17
st x+,r1

ret

Итого: - 2слова, -2такта
Кстати, думаю что еще пару-тройку слов/тактов можно еще скушать...
Но это в следующий раз, когда мозк потребует деятельности...

P.S. Просьба не флеймить и высказываться только по существу...
Go to the top of the page
 
+Quote Post
Guest_=AVR=_*
сообщение Nov 13 2007, 23:50
Сообщение #2





Guests






Цитата
Кстати, думаю что еще пару-тройку слов/тактов можно еще скушать...
И не пару-тройку, а с десяток запросто - я свой код даже не пытался оптимизировать, а просто тупо перевел с dsPIC ASM, на котором написал оригинал. А вот dsPIC-версия оптимизирована - там всего 16 тактов, и хрен что ты там улучшишь smile.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 14 2007, 00:05
Сообщение #3


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=AVR= @ Nov 14 2007, 02:50) *
А вот dsPIC-версия оптимизирована - там всего 16 тактов, и хрен что ты там улучшишь smile.gif
Дык надо бы увидеть этот код для начала smile.gif
конечно с 16 тактов сложно чего-нить оптимизировать... да и dsPIC я не знаю,
но все равно было бы интересно посмотреть в качестве изучения незнакомой архитектуры...
Go to the top of the page
 
+Quote Post
Прохожий
сообщение Nov 14 2007, 00:18
Сообщение #4


Cундук
*****

Группа: Участник
Сообщений: 1 478
Регистрация: 13-11-06
Из: Ростов-на-Дону
Пользователь №: 22 269



Цитата(singlskv @ Nov 14 2007, 03:05) *
Дык надо бы увидеть этот код для начала smile.gif
конечно с 16 тактов сложно чего-нить оптимизировать... да и dsPIC я не знаю,
но все равно было бы интересно посмотреть в качестве изучения незнакомой архитектуры...

Присоединяюсь.
Go to the top of the page
 
+Quote Post
Guest_=AVR=_*
сообщение Nov 14 2007, 00:20
Сообщение #5





Guests






А пожалуйста:

Код
;------------------------------------------------------------------
; Converts an unsigned integer N in w0 to a 5-byte ASCII numerical string [w4]
; using a reciprocal multiplication and fractional conversion techniques
; 16 clocks+RETURN, 17 program words
itoa:
magic10 = 429497; =~ 2^32/10000

    mov    #magic10 >> 16,w1
    mul.uu    w1,w0,w2; w3:w2 = partial product MSWs
    mov    #magic10 & 0xFFFF,w1
    mul.uu    w1,w0,w0; w1:w0 = partial product LSWs

    add    w1,w2,w0; w0 = fract(N%10000)
    mov    #'0',w2; w2 = ASCII bit mask
    addc.b    w3,w2,[w4++]; w3 = N/10000, store an ASCII MS character

    inc    w0,w0; Correct a remainder to use 16-bit ops

    mul.uu    w0,#10,w0; w1 = next ASCII digit (0..9 range), w0 = fractional remainder
    ior.b    w1,w2,[w4++]; Store a next ASCII character

    mul.uu    w0,#10,w0; Same as above, inline version
    ior.b    w1,w2,[w4++];

    mul.uu    w0,#10,w0; Same as above, inline version
    ior.b    w1,w2,[w4++];

    mul.uu    w0,#10,w0; Same as above, inline version
    ior.b    w1,w2,[w4++];

    return
;------------------------------------------------------------------


(Edit) Это универсальная версия - как для PIC24, так и для dsPIC. Версия только для dsPIC может быть на 4 слова короче, но на 2 такта дольше - четыре последних пары команд ставятся в DO Loop:

Код
        do          #3,1f       ; Repeat the block below 4 times
        mul.uu      w0,#10,w0   ; w1 = next ASCII digit (0..9 range), w0 = fractional remainder
1:      ior.b       w1,w2,[w4++]; Store a next ASCII character


Сообщение отредактировал =AVR= - Nov 14 2007, 00:44
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 14 2007, 00:35
Сообщение #6


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=AVR= @ Nov 14 2007, 03:20) *
А пожалуйста:
Код
...........................
Да,
красива....!!!
С такими режимами адресации, там действительно улучшать нечего....
Go to the top of the page
 
+Quote Post
=GM=
сообщение Nov 14 2007, 17:52
Сообщение #7


Ambidexter
*****

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



Цитата(singlskv @ Nov 13 2007, 23:19) *
Ну я быстрее... smile.gif Чиста редактируем код многоуважаемого =AVR= smile.gif Итого: - 2слова, -2такта
Кстати, думаю что еще пару-тройку слов/тактов можно еще скушать...
Но это в следующий раз, когда мозк потребует деятельности...

P.S. Просьба не флеймить и высказываться только по существу...

Если заменить фрагмент кода =AVR=, который вычисляет количество десятков тысяч, на нижеприведённый код (до метки fractoa), а остальное оставить, то можно уменьшить время выполнения, по крайней мере на 4 такта, в среднем ещё больше.

Код, тупо вычитающий десятки тысяч (макс.29, мин.10, в среднем 20)
Код
bin1:   subi       res0,0x10      ;
        sbci       res1,0x27      ;
        brpl       bin2        ;
        ldi        temp,0x30      ;digit 0
        subi       res0,0xF0      ;
        sbci       res1,0xD8      ;
        rjmp       eo1e4          ;
bin2:   subi       res0,0x10      ;
        sbci       res1,0x27      ;
        brpl       bin3        ;
        ldi        temp,0x31      ;digit 1
        subi       res0,0xF0      ;
        sbci       res1,0xD8      ;
        rjmp       eo1e4          ;
bin3:   subi       res0,0x10      ;
        sbci       res1,0x27      ;
        brpl       bin4        ;
        ldi        temp,0x32      ;digit 2
        subi       res0,0xF0      ;
        sbci       res1,0xD8      ;
        rjmp       eo1e4          ;
bin4:   subi       res0,0x10      ;
        sbci       res1,0x27      ;
        brpl       bin5        ;
        ldi        temp,0x33      ;digit 3
        subi       res0,0xF0      ;
        sbci       res1,0xD8      ;
        rjmp       eo1e4          ;
bin5:   sbci       res0,0x10      ;
        sbci       res1,0x27      ;
        brpl       bin6        ;
        ldi        temp,0x34      ;digit 4
        subi       res0,0xF0      ;
        sbci       res1,0xD8      ;
        rjmp       eo1e4          ;
bin6:   subi       res0,0x10      ;
        sbci       res1,0x27      ;
        brpl       bin7        ;
        ldi        temp,0x35      ;digit 5
        subi       res0,0xF0      ;
        sbci       res1,0xD8      ;
        rjmp       eo1e4          ;
bin7:   ldi        temp,0x36      ;digit 6
eo1e4:  st         x+,temp        ;


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Nov 14 2007, 20:20
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А если пофлеймить, то это выглядит так. Данная процедура, как правило, используется при выводе на дисплей или аналогичное устройство. Данное устройство в тысячи раз более медленное, чем МК. С учётом человеческого восприятия, вообще в миллионы раз более медленное. С учётом того, сколько данная процедура отнимает процессорного времени, то оптимизация её нецелесообразна. Ни по каким критериям.

В последнем проекте я оптимизировал процедуру вывода точки на графический дисплей. Здесь да! Стоит упираться. В результате оптимизации я увеличил производительность на тесте втрое. (Применял групповую обработку точек, расчёт границ и т.п.)
Go to the top of the page
 
+Quote Post
Guest_=AVR=_*
сообщение Nov 14 2007, 20:49
Сообщение #9





Guests






Данная процедура в моих изделиях (и в тысячах и тысячах аналогичнных систем) преобразует туеву хучу двоичных данных в ASCII для передачи их по UART и Ethernet в форматах/протоколах, принятых во многих промышленных стандартах. Таких преобразований - itoa, ltoa, ftoa, fixtoa - знаковых и беззнаковых, с управлением лидирующими/завершающими нулями и прочим форматированием/масштабированием, должно выполняться много десятков тысяч в секунду, и аналогии с дисплеем здесь так же уместны, как со взятием Бастилии. Применение готовых решений типа sprintf и даже штатных Xtoa не выдержит никакой критики, ибо убьет производительность в СОТНИ раз, что неудивительно
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Nov 14 2007, 21:57
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Тогда извиняюсь. Но "в сотни раз" это уж черезчур.

Можно не пользоваться библиотечными функциями, а написать свои. Максимально приближенным к АСМу языком. Потери никак не превысят 30%. С учётом подготовки данных, которая как правило в 5-10 раз превышает саму операцию - 30% преобразуются в 10-15.

Ваш выигрыш здесь обеспечен использованием большого числа регистров. В АСМовских программах оптимизация используемых регистров даёт великолепный выигрыш. Но это имеет свои недостатки. В данном небольшом кусочке вы задействовали 14 из 32 регистров. При таком написании говорить об вылизаности и универсальности проги очень сложно. При переносе в другой проект вы уверены, что там тоже будут свободны 14 этих же регистров? Как правило при написании АСМовой проги задействованы все регистры в зависимости от частоты использования. И вот вам придётся сохранять/загружать и выигрыш серьёзно падает. При работе с большим количеством переменных выигрыш АСМовой проги, как правило превращается в проигрыш.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 15 2007, 01:41
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=GM= @ Nov 14 2007, 20:52) *
Если заменить фрагмент кода =AVR=, который вычисляет количество десятков тысяч, на нижеприведённый код (до метки fractoa), а остальное оставить, то можно уменьшить время выполнения, по крайней мере на 4 такта, в среднем ещё больше.
Код, тупо вычитающий десятки тысяч (макс.29, мин.10, в среднем 20)
Код
................
        brpl       bin2    ;
...............
        brpl       bin3    ;
................

Наверное все-таки нужно brsh а не brpl ?
Ну и тактов по максимуму там 30 а не 29 smile.gif
Ну а если уже заниматься вычитаниями, то тогда так:
Код
bin1_1:
        subi    res0,0x40  ;-40000
        sbci    res1,0x9C
        brsh    bin1_3
        subi    res0,0xE0  ;+20000
        sbci    res1,0xB1
        brsh    bin1_2
        ldi     temp,0x30
        subi    res0,0xF0  ;+10000
        sbci    res1,0xD8
        brlo    bin1_5
        ldi     temp,0x31
        rjmp    bin1_6
bin1_2:
        ldi     temp,0x32
        subi    res0,0x10  ;-10000
        sbci    res1,0x27
        brlo    bin1_5
        ldi     temp,0x33
        rjmp    bin1_6
bin1_3:
        subi    res0,0x20  ;-20000
        sbci    res1,0x4E
        brsh    bin1_4
        ldi     temp,0x34
        subi    res0,0xF0  ;+10000
        sbci    res1,0xD8
        brlo    bin1_5
        ldi     temp,0x35
        rjmp    bin1_6
bin1_4:
        ldi     temp,0x36
        rjmp    bin1_6
bin1_5:
        subi    res0,0xF0  ;+10000
        sbci    res1,0xD8
bin1_6:
        st      x+,temp

Такты: min 13, max 16, среднее типа 15 smile.gif
Go to the top of the page
 
+Quote Post
Guest_=AVR=_*
сообщение Nov 15 2007, 08:52
Сообщение #12





Guests






Кажется, такой вариант приводил ник AD(?) на Телесистемах - так это ты и был? smile.gif

Цитата(SasaVitebsk @ Nov 15 2007, 00:57) *
И вот вам придётся сохранять/загружать и выигрыш серьёзно падает. При работе с большим количеством переменных выигрыш АСМовой проги, как правило превращается в проигрыш.
У меня этот выигрыш превращается только в еще больший выигрыш, т.к. все регистры - мои, а не дяди Компилятора или бабушки ОС smile.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 15 2007, 09:08
Сообщение #13


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=AVR= @ Nov 15 2007, 11:52) *
Кажется, такой вариант приводил ник AD(?) на Телесистемах - так это ты и был? smile.gif
Не, это был не я, на Телисистемы я практически никогда не захожу.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Nov 15 2007, 11:22
Сообщение #14


Ambidexter
*****

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



Цитата(singlskv @ Nov 15 2007, 01:41) *
Наверное все-таки нужно brsh а не brpl? Ну а если уже заниматься вычитаниями, то тогда так:Такты: min 13, max 16, среднее типа 15 smile.gif

Удивительно, как это разным людям приходят в голову одинаковые мысли(:-).

GM version singlskv version
Код
grant1: subi    res0,0x40     grant1: subi    res0,0x40     ;-40000
        sbci    res1,0x9C             sbci    res1,0x9C
        brsh    grant3                brsh    grant3
        subi    res0,0xE0             subi    res0,0xE0     ;+20000
        sbci    res1,0xB1             sbci    res1,0xB1
        brsh    grant2                brsh    grant2
        ldi     temp,0x30             ldi     temp,0x30
        subi    res0,0xF0             subi    res0,0xF0     ;+10000
        sbci    res1,0xD8             sbci    res1,0xD8
        brlo    grant5                brlo    grant5
                                      ldi     temp,0x31
        rjmp    grant4                rjmp    grant6
grant2: ldi     temp,0x32     grant2: ldi     temp,0x32
        subi    res0,0x10             subi    res0,0x10     ;-10000
        sbci    res1,0x27             sbci    res1,0x27
        brlo    grant5                brlo    grant5
                                      ldi     temp,0x33
        rjmp    grant4                rjmp    grant6
grant3: ldi     temp,0x36
        subi    res0,0x20     grant3: subi    res0,0x20     ;-20000
        sbci    res1,0x4E             sbci    res1,0x4E
        brsh    grant6                brsh    grant4
        ldi     temp,0x34             ldi     temp,0x34
        subi    res0,0xF0             subi    res0,0xF0     ;+10000
        sbci    res1,0xD8             sbci    res1,0xD8
        brlo    grant5                brlo    grant5
grant4: inc     temp                  ldi     temp,0x35
        rjmp    grant6                rjmp    grant6
                              grant4: ldi     temp,0x36
                                      rjmp    grant6
grant5: subi    res0,0xF0     grant5: subi    res0,0xF0     ;+10000
        sbci    res1,0xD8             sbci    res1,0xD8
grant6: st      x+,temp       grant6: st      x+,temp

Примерно такая штука стоит у меня в конвертере 24 бита в азки. Разница только в размере кода, у меня короче на 3 слова.

Да, удивительно, и подозрительно...Вас на какой фабрике программировали(:-)?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 15 2007, 16:50
Сообщение #15


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=GM= @ Nov 15 2007, 14:22) *
GM version singlskv version
Код
........................................

Примерно такая штука стоит у меня в конвертере 24 бита в азки. Разница только в размере кода, у меня короче на 3 слова.
Все правильно, у меня был точно такой же код как и у Вас, а потом я стал уранивать
длительности выполнения по разным веткам чтобы уменьшить максимум, ну и заодно среднее
чуть уменьшилось. Такты по разным веткам
GM version singlskv version
Код
15                            15
17                            15
16                            16
18                            16
17                            16
17                            16
11                            13
правда код конечно вырос.
Цитата
Да, удивительно, и подозрительно...Вас на какой фабрике программировали(:-)?
biggrin.gif biggrin.gif biggrin.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:28
Рейтинг@Mail.ru


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