|
itoa на asm, из темы "51 vs AVR"... |
|
|
|
Nov 13 2007, 23:19
|
дятел
    
Группа: Свой
Сообщений: 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
Ну я быстрее...  Чиста редактируем код многоуважаемого =AVR=  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. Просьба не флеймить и высказываться только по существу...
|
|
|
|
Guest_=AVR=_*
|
Nov 13 2007, 23:50
|
Guests

|
Цитата Кстати, думаю что еще пару-тройку слов/тактов можно еще скушать... И не пару-тройку, а с десяток запросто - я свой код даже не пытался оптимизировать, а просто тупо перевел с dsPIC ASM, на котором написал оригинал. А вот dsPIC-версия оптимизирована - там всего 16 тактов, и хрен что ты там улучшишь
|
|
|
|
Guest_=AVR=_*
|
Nov 14 2007, 00:20
|
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
|
|
|
|
|
Nov 14 2007, 00:35
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(=AVR= @ Nov 14 2007, 03:20)  А пожалуйста: Код ........................... Да, красива....!!! С такими режимами адресации, там действительно улучшать нечего....
|
|
|
|
|
Nov 14 2007, 17:52
|

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

|
Цитата(singlskv @ Nov 13 2007, 23:19)  Ну я быстрее...  Чиста редактируем код многоуважаемого =AVR=  Итого: - 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 ;
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Nov 14 2007, 20:20
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
А если пофлеймить, то это выглядит так. Данная процедура, как правило, используется при выводе на дисплей или аналогичное устройство. Данное устройство в тысячи раз более медленное, чем МК. С учётом человеческого восприятия, вообще в миллионы раз более медленное. С учётом того, сколько данная процедура отнимает процессорного времени, то оптимизация её нецелесообразна. Ни по каким критериям.
В последнем проекте я оптимизировал процедуру вывода точки на графический дисплей. Здесь да! Стоит упираться. В результате оптимизации я увеличил производительность на тесте втрое. (Применял групповую обработку точек, расчёт границ и т.п.)
|
|
|
|
Guest_=AVR=_*
|
Nov 14 2007, 20:49
|
Guests

|
Данная процедура в моих изделиях (и в тысячах и тысячах аналогичнных систем) преобразует туеву хучу двоичных данных в ASCII для передачи их по UART и Ethernet в форматах/протоколах, принятых во многих промышленных стандартах. Таких преобразований - itoa, ltoa, ftoa, fixtoa - знаковых и беззнаковых, с управлением лидирующими/завершающими нулями и прочим форматированием/масштабированием, должно выполняться много десятков тысяч в секунду, и аналогии с дисплеем здесь так же уместны, как со взятием Бастилии. Применение готовых решений типа sprintf и даже штатных Xtoa не выдержит никакой критики, ибо убьет производительность в СОТНИ раз, что неудивительно
|
|
|
|
|
Nov 15 2007, 01:41
|
дятел
    
Группа: Свой
Сообщений: 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  Ну а если уже заниматься вычитаниями, то тогда так: Код 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
|
|
|
|
Guest_=AVR=_*
|
Nov 15 2007, 08:52
|
Guests

|
Кажется, такой вариант приводил ник AD(?) на Телесистемах - так это ты и был?  Цитата(SasaVitebsk @ Nov 15 2007, 00:57)  И вот вам придётся сохранять/загружать и выигрыш серьёзно падает. При работе с большим количеством переменных выигрыш АСМовой проги, как правило превращается в проигрыш. У меня этот выигрыш превращается только в еще больший выигрыш, т.к. все регистры - мои, а не дяди Компилятора или бабушки ОС
|
|
|
|
|
Nov 15 2007, 11:22
|

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

|
Цитата(singlskv @ Nov 15 2007, 01:41)  Наверное все-таки нужно brsh а не brpl? Ну а если уже заниматься вычитаниями, то тогда так:Такты: min 13, max 16, среднее типа 15  Удивительно, как это разным людям приходят в голову одинаковые мысли(:-). 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 слова. Да, удивительно, и подозрительно...Вас на какой фабрике программировали(:-)?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Nov 15 2007, 16:50
|
дятел
    
Группа: Свой
Сообщений: 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 правда код конечно вырос. Цитата Да, удивительно, и подозрительно...Вас на какой фабрике программировали(:-)?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|