Zaliczyłem dość szerokie spectrum uP i uC ale akurat procesorki MicroChipa ominąłem, jakoś mam do nich awersję. Dzisiaj zerknąłem pobieżnie w pdfa, chyba źle postawiłeś tezę wątku, powinna brzmieć: "O wyższości ASM nad C w uC typu PIC". :)
Generalnie, programuję już wyłącznie w językach wysokiego poziomu, asm porzuciłem już dawno temu, kompilatory na "normalne" procesory sprawują się bardzo dobrze i produkują kod porównywalny do ASM, do tego szybciej. Jeżeli zależy mi na optymalizacji, to zerknę na generowany kod, ale najczęściej tylko po to aby złapać się za głowę i wyszeptać "coś ty napisał?". K.
dla funkcji zlicz: IAR C/C++ Compiler V5.30.1.50284/W32 for MSP430 102 bytes of CODE memory po właczeniu optymalizacji rozmiaru. Procesor MSP430 na pewno 16-bitowy. :) K.
W takim razie musiałbym porównywać wtedy do dsPIC30. No, ale w przyszłości może porównam też 16-bitowe. Możesz podać na jaki model kompilowałeś i wkleić kod ? S.
Właśnie sobie patrzę w opis MSP430FE42XA i widzę, że ma fajne adresowanie indexowe: MOV X(Rn),Y(Rm) MOV 2(R5),6(R6) M(2+R5)----> M(6+R6) W związku z tym myślę, że to jest kluczowe dla szybkości i objętości kodu. Ciekawe ile tych operacji ma w pętli sortowania. Szacuję, że 2 powinny wystarczyć, ale pewnie będzie ze 3 razy. S.
Dzięki. No faktycznie fajny kod. W pętli głównej sortowania użyli tylko 14 instrukcji. Jest to zrozumiałe, ze względu na możliwość adresowania indexowego. I faktycznie użyli X(Rn),Y(Rm). Tyle, że szacowałem, że użyją 3x, a użyli 5x. No i w wersji bajtowej.
1) Pokazuje to niefrasobliwość tego co robi kompilator, bo mając do dyspozycji przesuwanie całych słów, korzysta z bajtu. Ślepy indianin już zauważy, że te dwie instrukcje: ADRDOUT[j][0] = ADRDIOD[i][0] ADRDOUT[j][1] = ADRDIOD[i][1] mogą być wykonane za pomocą jednego rozkazu, a nie jak tutaj: mov.b 0x110A(R14),0x1114(R15) mov.b 0x110B(R14),0x1115(R15) Nigdy nie pisałem na MSP430, ale zapewne należałoby użyć: mov 0x110A(R14),0x1114(R15)
2) Albo tutaj. Kasowanie w pętli: 008022 clr.b 0x111E(R12) for(i = 0 ; i < k ; ++i) inc.w R12 cmp.w R13,R12 jl 0x8022 Tutaj 2 błędy: a) po co kasować po bajcie, skoro w pętli można kasować po słowie? i zmniejszyć liczbę obiegów o połowę! b) dlaczego nie jest użyta autoinkrementacja.
16-bitowy MSP430 nie ma rozkazów z inkrementacją R12++?
Reasumując: Kompilatory, mając do dyspozycji świetne rozwiązania techniczne producenta, doskonale je marnują. Dla zmylenia przeciwnika dają w opcjach rzekomą możliwość wybrania metody optymalizacji i żadna nie zauważa takiej gafy? S.
W dniu 06.04.2014 o 00:47 Sylwester Łazar snipped-for-privacy@alpro.pl pisze:
Tu masz jkeszcze w najnowszym As6.2, co prawda dał trochę ostrzeżeń ale skonpilował różnic w zasadzie nie ma, kod jest przesunięty bo inaczej zainicjowana jest tabela przerwań, zrobione to jest na nową ATmega88.
7a: a0 e0 ldi r26, 0x00 ; 0 7c: b1 e0 ldi r27, 0x01 ; 1 LICZV[i] = 0; // zerowanie tablicy for(i = 0 ; i < n ; ++i) ++LICZV[VDIOD[i]]; // po tych operacjach LICZV[i] będzie zawierała 7e: ed 91 ld r30, X+ 80: f0 e0 ldi r31, 0x00 ; 0 82: e2 5e subi r30, 0xE2 ; 226 84: fe 4f sbci r31, 0xFE ; 254 86: 80 81 ld r24, Z 88: 8f 5f subi r24, 0xFF ; 255 8a: 80 83 st Z, r24 char j; // zmienna pomocnicza for(i = 0 ; i < k ; ++i) LICZV[i] = 0; // zerowanie tablicy for(i = 0 ; i < n ; ++i) 8c: 81 e0 ldi r24, 0x01 ; 1 8e: a5 30 cpi r26, 0x05 ; 5 90: b8 07 cpc r27, r24 92: a9 f7 brne .-22 ; 0x7e <zlicz+0x12>
94: ef e1 ldi r30, 0x1F ; 31 96: f1 e0 ldi r31, 0x01 ; 1 98: ae e1 ldi r26, 0x1E ; 30 9a: b1 e0 ldi r27, 0x01 ; 1 ++LICZV[VDIOD[i]]; // po tych operacjach LICZV[i] będzie zawierała // liczbę wystąpień elementów o kluczu i for(i = 1 ; i < k ; ++i) LICZV[i] += LICZV[i-1]; // teraz LICZV[i] zawiera pozycje w posortowanej 9c: 9d 91 ld r25, X+ 9e: 80 81 ld r24, Z a0: 89 0f add r24, r25 a2: 81 93 st Z+, r24 LICZV[i] = 0; // zerowanie tablicy for(i = 0 ; i < n ; ++i) ++LICZV[VDIOD[i]]; // po tych operacjach LICZV[i] będzie zawierała // liczbę wystąpień elementów o kluczu i for(i = 1 ; i < k ; ++i) a4: 81 e0 ldi r24, 0x01 ; 1 a6: e5 32 cpi r30, 0x25 ; 37 a8: f8 07 cpc r31, r24 aa: c1 f7 brne .-16 ; 0x9c <zlicz+0x30>
ac: 84 e0 ldi r24, 0x04 ; 4 LICZV[i] += LICZV[i-1]; // teraz LICZV[i] zawiera pozycje w posortowanej // tablicy ostatniego elementu o kluczu i for(i = n-1 ; i >= 0 ; --i) { j=--LICZV[VDIOD[i]]; // aktualizacja LICZV ae: a8 2f mov r26, r24 b0: b0 e0 ldi r27, 0x00 ; 0 b2: fd 01 movw r30, r26 b4: e0 50 subi r30, 0x00 ; 0 b6: ff 4f sbci r31, 0xFF ; 255 b8: 90 81 ld r25, Z ba: c9 2f mov r28, r25 bc: d0 e0 ldi r29, 0x00 ; 0 be: c2 5e subi r28, 0xE2 ; 226 c0: de 4f sbci r29, 0xFE ; 254 c2: e8 81 ld r30, Y c4: e1 50 subi r30, 0x01 ; 1 c6: e8 83 st Y, r30 VDOUT[j] = VDIOD[i]; //wstawienie elementu na odpowiednią pozycję c8: f0 e0 ldi r31, 0x00 ; 0 ca: ef 01 movw r28, r30 cc: c7 5e subi r28, 0xE7 ; 231 ce: de 4f sbci r29, 0xFE ; 254 d0: 98 83 st Y, r25 ADRDOUT[j][0] = ADRDIOD[i][0]; // sortowanie adresów d2: ee 0f add r30, r30 d4: ff 1f adc r31, r31 d6: eb 5f subi r30, 0xFB ; 251 d8: fe 4f sbci r31, 0xFE ; 254 da: aa 0f add r26, r26 dc: bb 1f adc r27, r27 de: a1 5f subi r26, 0xF1 ; 241 e0: be 4f sbci r27, 0xFE ; 254 e2: 9c 91 ld r25, X e4: 90 83 st Z, r25 ADRDOUT[j][1] = ADRDIOD[i][1]; // sortowanie adresów e6: 11 96 adiw r26, 0x01 ; 1 e8: 9c 91 ld r25, X ea: 91 83 std Z+1, r25 ; 0x01 ++LICZV[VDIOD[i]]; // po tych operacjach LICZV[i] będzie zawierała // liczbę wystąpień elementów o kluczu i for(i = 1 ; i < k ; ++i) LICZV[i] += LICZV[i-1]; // teraz LICZV[i] zawiera pozycje w posortowanej // tablicy ostatniego elementu o kluczu i for(i = n-1 ; i >= 0 ; --i) ec: 81 50 subi r24, 0x01 ; 1 ee: df cf rjmp .-66 ; 0xae <zlicz+0x42>
000000f0 <main>: char ADRDIOD[5][2];//tablica adresów diod char ADRDOUT[5][2];//tablica adresów diod po posegregowaniu char LICZV[5]; // zawiera liczbę elementów o danej wartości
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.