[uquote="Starichok51",url="/forum/viewtopic.php?p=4360827#p4360827"]деление во МНОГО раз медленнее, чем сложение или вычитание.
быстрее 9 раз сложить и 9 раз вычесть, чем один раз разделить.[/uquote]
Вы когда пытаетесь быстрее паровоза бежать, смотрите, получается ли у вас это.
А то у вас это УЖЕ не получается, но вы об этом ЕЩЁ не знаете.
Посмотрел, какой код генерирует компилятор для вот такого кода:
Код: Выделить всё
display_symbols[3] = display_u / 1000;
display_u = display_u % 1000;
display_symbols[4] = display_u / 100;
display_u = display_u % 100;
display_symbols[5] = display_u / 10;
Спойлер
Код: Выделить всё
Это код функции, поэтому display_u уже в регистрах r25:r24
display_symbols[3] = display_u / 1000;
210: 68 ee ldi r22, 0xE8 ; 232 --- 1000
212: 73 e0 ldi r23, 0x03 ; 3
214: 0e 94 4f 10 call 0x209e ; 0x209e <__udivmodhi4>
218: 60 93 61 01 sts 0x0161, r22
display_u = display_u % 1000;
display_symbols[4] = display_u / 100;
21c: 64 e6 ldi r22, 0x64 ; 100
21e: 70 e0 ldi r23, 0x00 ; 0
220: 0e 94 4f 10 call 0x209e ; 0x209e <__udivmodhi4>
224: 60 93 62 01 sts 0x0162, r22
display_u = display_u % 100;
display_symbols[5] = display_u / 10;
228: 6a e0 ldi r22, 0x0A ; 10
22a: 70 e0 ldi r23, 0x00 ; 0
22c: 0e 94 4f 10 call 0x209e ; 0x209e <__udivmodhi4>
230: 60 93 63 01 sts 0x0163, r22
234: 08 95 ret
0000209e <__udivmodhi4>:
209e: aa 1b sub r26, r26
20a0: bb 1b sub r27, r27
20a2: 51 e1 ldi r21, 0x11 ; 17
20a4: 07 c0 rjmp .+14 ; 0x20b4 <__udivmodhi4_ep>
000020a6 <__udivmodhi4_loop>:
20a6: aa 1f adc r26, r26
20a8: bb 1f adc r27, r27
20aa: a6 17 cp r26, r22
20ac: b7 07 cpc r27, r23
20ae: 10 f0 brcs .+4 ; 0x20b4 <__udivmodhi4_ep>
20b0: a6 1b sub r26, r22
20b2: b7 0b sbc r27, r23
000020b4 <__udivmodhi4_ep>:
20b4: 88 1f adc r24, r24
20b6: 99 1f adc r25, r25
20b8: 5a 95 dec r21
20ba: a9 f7 brne .-22 ; 0x20a6 <__udivmodhi4_loop>
20bc: 80 95 com r24
20be: 90 95 com r25
20c0: bc 01 movw r22, r24
20c2: cd 01 movw r24, r26
20c4: 08 95 ret
В каком месте тут "во МНОГО" (большими жЫрнЫми буквами, для усиления эффекта) раз медленнее, если оно делается всё тем же способом сложения-вычитания?
Не надо пытаться быть умнее хорошего компилятора. Пишите нормальный человекопонятный код, а не дебильные циклы "двадцатьпервым пальцем" и всё будет ок.
Заменил ради интереса на предлагаемые циклы:
Код: Выделить всё
//display_symbols[3] = display_u / 1000;
//display_u = display_u % 1000;
//display_symbols[4] = display_u / 100;
//display_u = display_u % 100;
//display_symbols[5] = display_u / 10;
while( display_u>1000 ) { display_symbols[3]++; display_u = display_u - 1000; }
while( display_u>100 ) { display_symbols[4]++; display_u = display_u - 100; }
while( display_u>10 ) { display_symbols[5]++; display_u = display_u - 10; }
Получил такой листинг:
Спойлер
Код: Выделить всё
Это код функции, поэтому display_u уже в регистрах r25:r24
210: 20 91 61 01 lds r18, 0x0161
214: 31 e0 ldi r19, 0x01 ; 1
216: 32 0f add r19, r18
while( display_u>1000 ) { display_symbols[3]++; display_u = display_u - 1000; }
218: 89 3e cpi r24, 0xE9 ; 233
21a: 43 e0 ldi r20, 0x03 ; 3
21c: 94 07 cpc r25, r20
21e: 20 f0 brcs .+8 ; 0x228 <display_U+0x8a>
220: 88 5e subi r24, 0xE8 ; 232
222: 93 40 sbci r25, 0x03 ; 3
224: 23 2f mov r18, r19
226: f6 cf rjmp .-20 ; 0x214 <display_U+0x76>
228: 20 93 61 01 sts 0x0161, r18
22c: 20 91 62 01 lds r18, 0x0162
230: 31 e0 ldi r19, 0x01 ; 1
232: 32 0f add r19, r18
while( display_u>100 ) { display_symbols[4]++; display_u = display_u - 100; }
234: 85 36 cpi r24, 0x65 ; 101
236: 91 05 cpc r25, r1
238: 20 f0 brcs .+8 ; 0x242 <display_U+0xa4>
23a: 84 56 subi r24, 0x64 ; 100
23c: 91 09 sbc r25, r1
23e: 23 2f mov r18, r19
240: f7 cf rjmp .-18 ; 0x230 <display_U+0x92>
242: 20 93 62 01 sts 0x0162, r18
246: 20 91 63 01 lds r18, 0x0163
24a: 31 e0 ldi r19, 0x01 ; 1
24c: 32 0f add r19, r18
while( display_u>10 ) { display_symbols[5]++; display_u = display_u - 10; }
24e: 8b 30 cpi r24, 0x0B ; 11
250: 91 05 cpc r25, r1
252: 18 f0 brcs .+6 ; 0x25a <display_U+0xbc>
254: 0a 97 sbiw r24, 0x0a ; 10
256: 23 2f mov r18, r19
258: f8 cf rjmp .-16 ; 0x24a <display_U+0xac>
25a: 20 93 63 01 sts 0x0163, r18
25e: 08 95 ret
После этой замены размер прошивки увеличился на 42 байта, и это еще не добавлена прединициализация элементов display_symbols нулем или 0x30 (впрочем, она не должна существенно изменить размер кода).
Что мы видим - на получение одного значения теперь надо не 6 опкодов вызова функции, а 14/13/12.
Функция размером 20 машинных операций/опкодов. Соответственно решение с циклом while займет больше места ( 3*6 + 20 < 3*13) в прошивке даже если в коде будет только три цикла.
Вызываемая функция - делает ту же математику вычитанием, соответственно не может быть "во МНОГО" раз медленнее.
Так в реальной программе всё равно будет использоваться деление, а операций будет не три, а больше - то использование нормальных функций, а не цикла - выгоднее по размеру и не уступает по скорости.
Кроме того, прикладной программист может и не знать всех оптимизационных трюков,
которые заложили разработчики компилятора, а в некоторых случаях - и возможностей процессора.
Не учите людей говнокодерской х-не.
[uquote="razbudin",url="/forum/viewtopic.php?p=4361465#p4361465"]Значит буду попытаться избегать деления, хотя сейчас конечно мне это не актуально. Спасибо.[/uquote]