|
|
  |
Помогите оптимизировать, Сишный код для авр |
|
|
|
Oct 8 2008, 16:21
|
Группа: Новичок
Сообщений: 4
Регистрация: 31-05-08
Пользователь №: 37 943

|
Помогите оптимизировать код, надо его сделать побыстрее, очень не хочется уменьшать разрядность. . unsigned char pwma[256], pwmb[256], pwmc[256]; unsigned char pwmstep; // PWM main interrupt interrupt [TIM2_COMP] void timer2_comp_isr(void) { // Place your code here PORTA=pwma[pwmstep]; PORTB=pwmb[pwmstep]; PORTC=pwmc[pwmstep]; pwmstep++; } Компилятор (кодевижн) выдает такой листинг: Код ; 189 // PWM main interrupt ; 190 interrupt [TIM2_COMP] void timer2_comp_isr(void) ; 191 { _timer2_comp_isr: ST -Y,R30 ST -Y,R31 IN R30,SREG ST -Y,R30 ; 192 // Place your code here ; 193 PORTA=pwma[pwmstep]; MOV R30,R9 LDI R31,0 SUBI R30,LOW(-_pwma) SBCI R31,HIGH(-_pwma) LD R30,Z OUT 0x1B,R30 ; 194 PORTB=pwmb[pwmstep]; MOV R30,R9 LDI R31,0 SUBI R30,LOW(-_pwmb) SBCI R31,HIGH(-_pwmb) LD R30,Z OUT 0x18,R30 ; 195 PORTC=pwmc[pwmstep]; MOV R30,R9 LDI R31,0 SUBI R30,LOW(-_pwmc) SBCI R31,HIGH(-_pwmc) LD R30,Z OUT 0x15,R30 ; 196 pwmstep++; INC R9 ; 197 } _0xF0: LD R30,Y+ OUT SREG,R30 LD R31,Y+ LD R30,Y+ RETI ; 198
|
|
|
|
|
Oct 8 2008, 18:30
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Я идею подам, остальные результативно поругают  Из трех массивов сделать один, расположив данные из них как [pwma0][pwmb0][pwmc0]...[pwmaN][pwmbN][pwmcN], и: Код PORTA = thatArray[pwmstep]; PORTB = thatArray[pwmstep + 1]; PORTC = thatArray[pwmstep + 2]; pwmstep += 3; Но ручками переписать на asm'е было бы самое то (он для того и нужен - оптимизировать).
|
|
|
|
|
Oct 9 2008, 00:09
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(sergeeff @ Oct 8 2008, 21:14)  Можно попробовать так (компилятора нет под рукой для AVR): Навскидку: размер получившегося массива 3 байта, компилятор будет вызывать умножение на 3. Можно попробовать вот так: Код typedef struct { uint8_t a; uint8_t b; uint8_t c; } pwm_point_t
union { pwm_point_t point[256]; uint8_t raw[]; } PWM; uint8_t *pIndex = PWM.raw;
// PWM main interrupt interrupt [TIM2_COMP] void timer2_comp_isr(void) { // Place your code here PORTA = *pIndex++; PORTB = *pIndex++; PORTC = *pIndex++; if(pIndex == (uint8_t *)(&PWM + 1)) { pIndex = PWM.raw; } } PWM.point[x] использовать для заполнения массива. По ним тоже можно шагать указателем.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 9 2008, 07:42
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Огурцов @ Oct 9 2008, 09:49)  На сколько я помню свои эксперименты, результат компиляции будет совершенно одинаков с PORTA=pwm[pwmstep++]; Не должен. *pIndex++ указателю один раз за 256 итераций присваивается значение адреса, и дальше вычислять смещение уже не нужно. Собственно проверить-то просто: CODE typedef struct { uint8_t a; uint8_t b; uint8_t c; } pwm_point_t;
union { pwm_point_t point[256]; uint8_t raw[]; } PWM; uint8_t *pIndex = PWM.raw; uint16_t Index; // PWM main interrupt ISR(TIMER1_OVF_vect) { // Place your code here uint8_t *pTmp = pIndex; PORTD = *pTmp++; PORTB = *pTmp++; PORTC = *pTmp++; if(++pTmp == (uint8_t *)(&PWM + 1)) { pTmp = PWM.raw; } pIndex = pTmp; } ISR(TIMER0_OVF_vect) { // Place your code here uint16_t Tmp = Index; PORTD = PWM.raw[Tmp++]; PORTB = PWM.raw[Tmp++]; PORTC = PWM.raw[Tmp++]; if(++Tmp == sizeof(PWM.raw)) Tmp = 0; Index = Tmp; } и листинг (WinAVR). Первый вариант: CODE 54 .section .text.__vector_9,"ax",@progbits 55 .global __vector_9 57 __vector_9: 58 .LFB25: 59 .LSM0: 60 /* prologue: frame size=0 */ 61 0000 1F92 push __zero_reg__ 62 0002 0F92 push __tmp_reg__ 63 0004 0FB6 in __tmp_reg__,__SREG__ 64 0006 0F92 push __tmp_reg__ 65 0008 1124 clr __zero_reg__ GAS LISTING D:/Temp/ccreYbyY.s page 2
66 000a 8F93 push r24 67 000c AF93 push r26 68 000e BF93 push r27 69 0010 CF93 push r28 70 0012 DF93 push r29 71 0014 EF93 push r30 72 0016 FF93 push r31 73 /* prologue end (size=12) */ 74 .LBB19: 75 .LSM1: 76 0018 A091 0000 lds r26,pIndex ; pTmp.68, pIndex 77 001c B091 0000 lds r27,(pIndex)+1 ; pTmp.68, pIndex 78 .LVL0: 79 .LSM2: 80 0020 FD01 movw r30,r26 ; pTmp.69, pTmp.68 81 .LVL1: 82 0022 8191 ld r24,Z+ ; D.2508, 83 0024 82BB out 50-0x20,r24 ; , D.2508 84 .LSM3: 85 0026 ED01 movw r28,r26 ; , pTmp.68 86 0028 8981 ldd r24,Y+1 ; temp.66, 87 002a 88BB out 56-0x20,r24 ; , temp.66 88 .LSM4: 89 002c 8181 ldd r24,Z+1 ; temp.67, 90 002e 85BB out 53-0x20,r24 ; , temp.67 91 .LSM5: 92 0030 1496 adiw r26,4 ; pTmp, 93 .LVL2: 94 0032 80E0 ldi r24,hi8(PWM+768) ; , 95 0034 A030 cpi r26,lo8(PWM+768) ; pTmp, 96 0036 B807 cpc r27,r24 ; pTmp, 97 0038 01F4 brne .L2 ; , 98 .LSM6: 99 003a A0E0 ldi r26,lo8(PWM) ; pTmp, 100 003c B0E0 ldi r27,hi8(PWM) ; pTmp, 101 .L2: 102 .LSM7: 103 003e B093 0000 sts (pIndex)+1,r27 ; pIndex, pTmp 104 0042 A093 0000 sts pIndex,r26 ; pIndex, pTmp 105 .LBE19: 106 /* epilogue: frame size=0 */ 107 0046 FF91 pop r31 108 0048 EF91 pop r30 109 004a DF91 pop r29 110 004c CF91 pop r28 111 004e BF91 pop r27 112 0050 AF91 pop r26 113 0052 8F91 pop r24 114 0054 0F90 pop __tmp_reg__ 115 0056 0FBE out __SREG__,__tmp_reg__ 116 0058 0F90 pop __tmp_reg__ 117 005a 1F90 pop __zero_reg__ 118 005c 1895 reti Второй вариант: CODE 123 .section .text.__vector_8,"ax",@progbits 124 .global __vector_8 126 __vector_8: 127 .LFB26: 128 .LSM8: 129 /* prologue: frame size=0 */ 130 0000 1F92 push __zero_reg__ 131 0002 0F92 push __tmp_reg__ 132 0004 0FB6 in __tmp_reg__,__SREG__ 133 0006 0F92 push __tmp_reg__ 134 0008 1124 clr __zero_reg__ 135 000a 2F93 push r18 136 000c 4F93 push r20 137 000e 5F93 push r21 138 0010 8F93 push r24 139 0012 9F93 push r25 140 0014 AF93 push r26 141 0016 BF93 push r27 142 0018 EF93 push r30 143 001a FF93 push r31 144 /* prologue end (size=14) */ 145 .LBB20: 146 .LSM9: 147 001c 4091 0000 lds r20,IndexRaw ; Tmp, IndexRaw 148 0020 5091 0000 lds r21,(IndexRaw)+1 ; Tmp, IndexRaw 149 .LVL3: 150 .LSM10: 151 0024 80E0 ldi r24,lo8(PWM) ; tmp47, 152 0026 90E0 ldi r25,hi8(PWM) ; tmp47, 153 0028 FA01 movw r30,r20 ; tmp48, Tmp 154 002a E80F add r30,r24 ; tmp48, tmp47 155 002c F91F adc r31,r25 ; tmp48, tmp47 156 002e 2081 ld r18,Z ; D.2520, PWM.raw 157 0030 22BB out 50-0x20,r18 ; , D.2520 158 0032 FA01 movw r30,r20 ; Tmp.97, Tmp 159 .LVL4: 160 0034 3196 adiw r30,1 ; Tmp.97, 161 .LSM11: 162 0036 DF01 movw r26,r30 ; tmp51, Tmp.97 163 0038 A80F add r26,r24 ; tmp51, tmp47 164 003a B91F adc r27,r25 ; tmp51, tmp47 165 003c 2C91 ld r18,X ; temp.100, PWM.raw 166 003e 28BB out 56-0x20,r18 ; , temp.100 167 .LSM12: 168 0040 FD01 movw r30,r26 ; Tmp.97, tmp51 169 0042 8181 ldd r24,Z+1 ; temp.101, PWM.raw 170 0044 85BB out 53-0x20,r24 ; , temp.101 171 .LSM13: 172 0046 4C5F subi r20,lo8(-(4)) ; Tmp, 173 0048 5F4F sbci r21,hi8(-(4)) ; Tmp, 174 004a 5093 0000 sts (IndexRaw)+1,r21 ; IndexRaw, Tmp 175 004e 4093 0000 sts IndexRaw,r20 ; IndexRaw, Tmp 176 .LBE20: 177 /* epilogue: frame size=0 */ 178 0052 FF91 pop r31 179 0054 EF91 pop r30 180 0056 BF91 pop r27 181 0058 AF91 pop r26 182 005a 9F91 pop r25 183 005c 8F91 pop r24 184 005e 5F91 pop r21 185 0060 4F91 pop r20 186 0062 2F91 pop r18 187 0064 0F90 pop __tmp_reg__ 188 0066 0FBE out __SREG__,__tmp_reg__ 189 0068 0F90 pop __tmp_reg__ 190 006a 1F90 pop __zero_reg__ 191 006c 1895 reti Третий вариант: CODE 196 .section .text.__vector_4,"ax",@progbits 197 .global __vector_4 199 __vector_4: 200 .LFB27: 201 .LSM14: 202 /* prologue: frame size=0 */ 203 0000 1F92 push __zero_reg__ 204 0002 0F92 push __tmp_reg__ 205 0004 0FB6 in __tmp_reg__,__SREG__ 206 0006 0F92 push __tmp_reg__ 207 0008 1124 clr __zero_reg__ 208 000a 2F93 push r18 209 000c 8F93 push r24 210 000e 9F93 push r25 211 0010 EF93 push r30 212 0012 FF93 push r31 213 /* prologue end (size=10) */ 214 .LBB21: 215 .LSM15: 216 0014 2091 0000 lds r18,Index ; Tmp, Index 217 .LVL5: 218 .LSM16: 219 0018 822F mov r24,r18 ; D.2529, Tmp 220 001a 9927 clr r25 ; D.2529 221 001c FC01 movw r30,r24 ; tmp50, D.2529 222 001e EE0F lsl r30 ; tmp50 223 0020 FF1F rol r31 ; tmp50 224 .LVL6: 225 0022 E80F add r30,r24 ; tmp50, D.2529 226 0024 F91F adc r31,r25 ; tmp50, D.2529 227 0026 E050 subi r30,lo8(-(PWM)) ; tmp50, 228 0028 F040 sbci r31,hi8(-(PWM)) ; tmp50, 229 002a 8081 ld r24,Z ; D.2530, <variable>.a 230 002c 82BB out 50-0x20,r24 ; , D.2530 231 .LSM17: 232 002e 8181 ldd r24,Z+1 ; D.2532, <variable>.b 233 0030 88BB out 56-0x20,r24 ; , D.2532 234 .LSM18: 235 0032 8281 ldd r24,Z+2 ; D.2534, <variable>.c 236 0034 85BB out 53-0x20,r24 ; , D.2534 237 .LBE21: 238 /* epilogue: frame size=0 */ 239 0036 FF91 pop r31 240 0038 EF91 pop r30 GAS LISTING D:/Temp/ccreYbyY.s page 5
241 003a 9F91 pop r25 242 003c 8F91 pop r24 243 003e 2F91 pop r18 244 0040 0F90 pop __tmp_reg__ 245 0042 0FBE out __SREG__,__tmp_reg__ 246 0044 0F90 pop __tmp_reg__ 247 0046 1F90 pop __zero_reg__ 248 0048 1895 reti Итого, победил sergeeff. Хотя другой компилятор может дать другие результаты. Совершенно непонятно, зачем компилятор в первом случае задействовал Y.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 9 2008, 20:04
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
Однако, радует то, что я все же не сглючил. Вот во что компилится инициализация массива с использованием индекса Код @000000D0: Get_serial_number 37: { +000000D0: 01FC MOVW R30,R24 Copy register pair 39: aValue[0] = (unsigned char)(Device_serial_number_3 >> 24); +000000D1: ED83 LDI R24,0xD3 Load immediate +000000D2: 8380 STD Z+0,R24 Store indirect with displacement 40: aValue[1] = (unsigned char)(Device_serial_number_3 >> 16); +000000D3: E987 LDI R24,0x97 Load immediate +000000D4: 8381 STD Z+1,R24 Store indirect with displacement 41: aValue[2] = (unsigned char)(Device_serial_number_3 >> 8); +000000D5: E585 LDI R24,0x55 Load immediate +000000D6: 8382 STD Z+2,R24 Store indirect with displacement 42: aValue[3] = (unsigned char)(Device_serial_number_3 >> 0); +000000D7: E082 LDI R24,0x02 Load immediate +000000D8: 8383 STD Z+3,R24 Store indirect with displacement 43: aValue[4] = (unsigned char)(Device_serial_number_2 >> 24); +000000D9: E284 LDI R24,0x24 Load immediate +000000DA: 8384 STD Z+4,R24 Store indirect with displacement А это с использованием указателя Код +000000D0: 01FC MOVW R30,R24 Copy register pair 56: *aValue++ = (unsigned char)(Device_serial_number_3 >> 24); +000000D1: ED83 LDI R24,0xD3 Load immediate +000000D2: 9381 ST Z+,R24 Store indirect and postincrement 57: *aValue++ = (unsigned char)(Device_serial_number_3 >> 16); +000000D3: E987 LDI R24,0x97 Load immediate +000000D4: 9381 ST Z+,R24 Store indirect and postincrement 58: *aValue++ = (unsigned char)(Device_serial_number_3 >> 8); +000000D5: E585 LDI R24,0x55 Load immediate +000000D6: 9381 ST Z+,R24 Store indirect and postincrement 59: *aValue++ = (unsigned char)(Device_serial_number_3 >> 0); +000000D7: E082 LDI R24,0x02 Load immediate +000000D8: 9381 ST Z+,R24 Store indirect and postincrement 60: *aValue++ = (unsigned char)(Device_serial_number_2 >> 24); +000000D9: E284 LDI R24,0x24 Load immediate +000000DA: 8380 STD Z+0,R24 Store indirect with displacement Т.е. разница, конечно, есть, но только не в размере и не в скорости выполнения. И такое сохранится до размера массива до 64 байт, т.е. пока будет хватать смещения (6 бит) в команде STD Z+disp, *. Для LDD могло бы быть так же.
Сообщение отредактировал Огурцов - Oct 9 2008, 20:15
|
|
|
|
|
Oct 14 2008, 07:38
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(SysRq @ Oct 8 2008, 22:30)  Из трех массивов сделать один, расположив данные из них как [pwma0][pwmb0][pwmc0]...[pwmaN] Так лучше. Тогда получается Код LD Yh,high(pwmstep) LD Yl,low(pwmstep) ; load pointer
LD tmp,Y+ OUT PORTA,tmp LD tmp,Y+ OUT PORTB,tmp LD tmp,Y+ OUT PORTC,tmp
ST high(pwmstep),Yh ST low(pwmstep),Yl ; save pointer 17 циклов. Если unsigned char pwm [3][256], то нужно добавить inc Yh после каждого OUT - это дополнительно 3 цикла, плюс вычислить новый pwmstep это пахнет ещё 4-мя цмклами.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|