Мелкие вопросы по МК и ПЛИС.
Вот это уже ближе к делу 
- Реклама
Ладно... С30 PIC24...
39 байт ROM, 0 байт RAM и 13 cycles...

39 байт ROM, 0 байт RAM и 13 cycles...
"Я не даю готовых решений, я заставляю думать!"(С)
Хмм... Код покажи.zero648 писал(а):На асме AVR это занимает 34 байта ROM, 0 RAM и 20 циклов
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вход - r17:r16, выход - r1:r0
Может, у кого еще получится ужать код
Код: Выделить всё
movw r18, r16
swap r19
andi r19, $0f
swap r18
andi r18, $0f
andi r17, $0f
andi r16, $0f
ldi r20, 10
mul r18, r20
add r16, r0
mul r19, r20
add r17, r0
ldi r20, 100
mul r17, r20
clr r17
add r0, r16
adc r1, r17
- Реклама
У вас без разбора из ниблов в байты: 20 байт, 13 тактов. Красиво!zero648 писал(а):Может, у кого еще получится ужать код
С умножением здорово сэкономил!
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
в AVR, в режиме Normal при разрешении прерывания по совпадению счетчик продолжает считать дальше или сбрасывается ?
Tell Me The Truth
Вот только привирать... некрасиво...Kavka писал(а): 13 тактов. Красиво!
3*2 + 14*1 = 20 тактов... да и то... на Мега-тру-АСМ-джедайстве..
Компилятор СИ не смог одолеть архитектуру времён развитого АСМоциализма и пасущихся мамонтов...
А вот это... действительно красиво... С30... GCC кстати...
Код: Выделить всё
56: X=D*1000 + C*100 + B*10 + A;
02A2 97B85F mov.w [w15-6],w0 // Загружаем А, B, C и D
02A4 97B94F mov.w [w15-8],w2
02A6 97BA3F mov.w [w15-10],w4
02A8 97BBFF mov.w [w15-2],w7
02AA 203E86 mov.w #0x3e8,w6 // Умножаем и складываем
02AC B98006 mul.ss w0,w6,w0
02AE 200646 mov.w #0x64,w6
02B0 B99106 mul.ss w2,w6,w2
02B2 400002 add.w w0,w2,w0
02B4 B9226A mul.su w4,#10,w4
02B6 400004 add.w w0,w4,w0
02B8 400007 add.w w0,w7,w0
02BA 9FBFE0 mov.w w0,[w15-4] // Получаем результат
57:
"Я не даю готовых решений, я заставляю думать!"(С)
Это верно для полного кода приведённого zero648.HHIMERA писал(а):Вот только привирать... некрасиво...![]()
3*2 + 14*1 = 20 тактов... да и то... на Мега-тру-АСМ-джедайстве..![]()
Прочитай внимательно моё сообщение!!!
Я написал про основное преобразование, т.к. исходные цифры могут храниться в разном виде.
Спойлер
Выход ассемблера (без NOP-а)
Код: Выделить всё
ATmega32A memory use summary [bytes]:
Segment Begin End Code Data Used Size Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x000014 20 0 20 32768 0.1%
[.dseg] 0x000060 0x000060 0 0 0 2048 0.0%
[.eseg] 0x000000 0x000000 0 0 0 1024 0.0%
- Вложения
-
- test-bcd1.png
- (11.31 КБ) 382 скачивания
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Короче,
A - единицы;
B - десятки;
С - сотни;
В - тысячи;
X - результат.
В итоге:
Для X э [0, 9999]
Башка уже не варит в математике, пойду спать, завтра додумаю.
A - единицы;
B - десятки;
С - сотни;
В - тысячи;
X - результат.
В итоге:
Код: Выделить всё
X = A + (B<<3) + (B<<1) + (C<<6) + (C<<5) + (C<<2) + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);Башка уже не варит в математике, пойду спать, завтра додумаю.
Chettuser, 82 байта, 41 такт (против 20 байт, 13 тактов у zero648).
Можно ещё на несколько команд/тактов укоротить код направив выход в исходные регистры.
Для контроллеров где нет умножения пойдёт.
Можно ещё на несколько команд/тактов укоротить код направив выход в исходные регистры.
Для контроллеров где нет умножения пойдёт.
Спойлер
Код: Выделить всё
; input - r19,r18,r17,r16
; output - r21:r20
; R = A + (B<<3) + (B<<1)
; + (C<<6) + (C<<5) + (C<<2)
; + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);
.def rD = r19
.def rC = r18
.def rB = r17
.def rA = r16
.def rRL = r20
.def rRH = r21
mov rRL, rA ; RES = A
mov rRH, rD ; RES = RES + (D << 8)
lsl rD ; D << 9
add rRH, rD ; RES = RES + (D << 9)
lsl rB ; B << 1
add rRL, rB ; RES = RES + (B << 1)
lsl rB ; B << 2
lsl rB ; B << 3
add rRL, rB ; RES = RES + (B << 3)
.undef rB
.def rCH = r17
clr rCH
lsl rC ; C << 1
lsl rC ; C << 2
add rRL, rC ; RES = RES + (C << 2)
lsl rC ; C << 3
lsl rC ; C << 4
lsl rC
rol rCH ; C << 5 ; (rCH:rC)
add rRL, rC
adc rRH, rCH ; RES = RES + (C << 5)
lsl rC
rol rCH ; C << 6
add rRL, rC
adc rRH, rCH ; RES = RES + (C << 6)
.undef rCH
.def rDH = r17
clr rDH
lsl rD ; D << 1
lsl rD ; D << 2
lsl rD ; D << 3
add rRL, rD ; RES = RES + (C << 2)
lsl rD ; C << 4
lsl rD
rol rDH ; D << 5 ; (rDH:rD)
add rRL, rD
adc rRH, rDH ; RES = RES + (D << 5)
lsl rD
rol rDH ; D << 6 ; (rDH:rD)
add rRL, rD
adc rRH, rDH ; RES = RES + (D << 6)
lsl rD
rol rDH ; D << 7 ; (rDH:rD)
add rRL, rD
adc rRH, rDH ; RES = RES + (D << 7)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Kavka писал(а):Chettuser, 82 байта, 41 такт (против 20 байт, 13 тактов у zero648).
Можно ещё на несколько команд/тактов укоротить код направив выход в исходные регистры.
Что в лужу...
Вспомните, о чём писал вопрошающий...
Chettuser писал(а):У меня не суперкомпьютер! А всего лишь скромные PIC16/18.
Chettuser писал(а):Опять ассемблер![]()
В сети ассемблера завались, а вот на Сях...
"Я не даю готовых решений, я заставляю думать!"(С)
Я на работе, занят, вечером буду оптимизировать. То что выше выкладывал можно еще математически укоротить. А потом уже по железу.
Дело то в том, что X э [0, 9999] не ограничивается задача, там вплоть до X э [0, 99999999].
Дело то в том, что X э [0, 9999] не ограничивается задача, там вплоть до X э [0, 99999999].
Какая разница, сколько знаков после запятой? Это лишь вопрос множителя. Все равно выводятся все значащие разряды БЕЗ ЗАПЯТОЙ, а запятая просто зажигается в нужном разряде.Chettuser писал(а): Дело то в том, что X э [0, 9999] не ограничивается задача, там вплоть до X э [0, 99999999].
Тогда берите PIC18 и HI-TECH...Chettuser писал(а):Я на работе, занят, вечером буду оптимизировать. То что выше выкладывал можно еще математически укоротить.
Код: Выделить всё
unsigned char A,B,C,D;
unsigned int X, Y;
//X=D*1000 + C*100 + B*10 + A;
X = D*1000;
X += C*100;
X += B*10;
X += A;
На PIC18F25K20@16MHz c PLL - 2,875мкС...
"Я не даю готовых решений, я заставляю думать!"(С)
X э [0, 99999999]КРАМ писал(а):Все равно выводятся все значащие разряды БЕЗ ЗАПЯТОЙ, а запятая просто зажигается в нужном разряде.
Где запятая?
На текущий момент:
занимает 3758 Instruction Cycles на MCC18. Ушёл спать, оптимизирую потом.
PS: Зря я не доверял компилятору!
код
занимает всего 676 Instruction Cycles

Спойлер
Код: Выделить всё
long int A, B, C, D, E, F, G, H, X;
int main()
{
A = 9;
B = 9;
C = 9;
D = 9;
E = 9;
F = 9;
G = 9;
H = 9;
X = A; // Прибавили еденицы
X = X + (B<<3) + (B<<1); // Прибавили десятки
X = X + (C<<6) + (C<<5) + (C<<2); // Прибавили сотни
X = X + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3); // Прибавили тысячи
X = X + (E<<13) + (E<<10) + (E<<9) + (E<<8) + (E<<4); // Прибавили десятки тысяч
X = X + (F<<16) + (F<<15) + (F<<10) + (F<<9) + (F<<7) + (F<<5); // Прибавили сотни тысяч
X = X + (G<<19) + (G<<18) + (G<<17) + (G<<16) + (G<<14) + (G<<9) + (G<<6); // Прибавили миллионы
X = X + (H<<23) + (H<<20) + (H<<19) + (H<<15) + (H<<12) + (H<<10) + (H<<9) + (H<<7); // Прибавили десятки миллионов
printf ("%d\n", X);
}PS: Зря я не доверял компилятору!
код
Код: Выделить всё
X = A + (B*10) + (C*100) + (D*1000) + (E*10000) + (F*100000) + (G*1000000) + (H*10000000);Не на то внимание обращаешь!HHIMERA писал(а):Вспомните, о чём писал вопрошающий...![]()
Chettuser, если в МК есть аппаратное умножение, то такое лучше написать как есть. Перевод на сдвиги может быть только хуже, так как элементарных операций получается значительно больше. Если умножителя нет, тогда со сдвигами может быть лучше.Chettuser писал(а):У меня не суперкомпьютер! А всего лишь скромные PIC16/18.
Могу продемонстрировать на примере AVR.
gcc version 4.3.3 (WinAVR 20100110)
Спойлер
Код: Выделить всё
unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
return ( d*1000 + c*100 + b*10 + a );
}
Без аппаратного умножения: 80 байт, 36 из них процедура умножения, 91..233 такта
Спойлер
Код: Выделить всё
unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
return ( a + (b<<3) + (b<<1) + (c<<6) + (c<<5) + (c<<2) + (d<<9) + (d<<8) + (d<<7) + (d<<6) + (d<<5) + (d<<3) );
}
Слегка модифицированный вариант - попытка отучить компилятор от циклов при сдвигах.
Спойлер
Код: Выделить всё
unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
unsigned int x;
unsigned int tmp;
x = a | (d<<8) + (d<<9);
b = b << 1;
x+= b;
b = b << 1;
b = b << 1;
x+= b;
c = c << 1;
c = c << 1; // c << 2
x+= c;
c = c << 1; // c << 3
c = c << 1; // c << 4
tmp = c;
tmp = tmp << 1; // c << 5
x+= tmp;
tmp = tmp << 1; // c << 6
x+= tmp;
d = d << 1;
d = d << 1;
d = d << 1; // d << 3
x+= d;
d = d << 1; // d << 4
tmp = d;
tmp = tmp << 1; // d << 5
x+= tmp;
tmp = tmp << 1; // d << 6
x+= tmp;
tmp = tmp << 1; // d << 7
x+= tmp;
return ( x );
}
Варианты с аппаратным умножением и со сдвигами имеют ещё такое преимущество как фиксированное время выполнения.
Ну вот, пока я писал, Chettuser сам получил результат.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вообще то... 442 Cycles на С18 и 440 Cycles на HI-TECH PICC18...Chettuser писал(а): Зря я не доверял компилятору!
кодзанимает всего 676 Instruction CyclesКод: Выделить всё
X = A + (B*10) + (C*100) + (D*1000) + (E*10000) + (F*100000) + (G*1000000) + (H*10000000);
"Я не даю готовых решений, я заставляю думать!"(С)


