-
51. Data: 2014-04-06 10:49:13
Temat: Odp: Odp: Odp: C vs. ASM na przykładzie PIC18F
Od: Sylwester Łazar <i...@a...pl>
> > Możesz wrzucić ten przykład do swojego kompilatora, na swój uK i pokazać
ile
> > rozkazów ma zlicz()?
>
> 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.
-
52. Data: 2014-04-06 10:59:18
Temat: Odp: Odp: Odp: C vs. ASM na przykładzie PIC18F
Od: Sylwester Łazar <i...@a...pl>
> 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ł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.
-
53. Data: 2014-04-06 12:46:31
Temat: Re: Odp: Odp: Odp: C vs. ASM na przykładzie PIC18F
Od: John Smith <d...@b...pl>
On 06-04-2014 10:49, Sylwester Łazar wrote:
>>> Możesz wrzucić ten przykład do swojego kompilatora, na swój uK i pokazać
> ile
>>> rozkazów ma zlicz()?
>>
>> 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 ?
Wykonałem kilkadziesiąt kompilacji na różne rodziny MSP430,
rozmiar półkompilatu zawsze ten sam: 102 bajty.
Listing kodu funkcji zlicz (zoptymalizowany)
for(i = 0 ; i < k ; ++i)
zlicz:
?cstart_end:
00801A 430C clr.w R12
00801C 425D 8000 mov.b &k,R13
008020 3C03 jmp 0x8028
LICZV[i] = 0; // zerowanie tablicy
008022 43CC 111E clr.b 0x111E(R12)
for(i = 0 ; i < k ; ++i)
008026 531C inc.w R12
for(i = 0 ; i < k ; ++i)
008028 9D0C cmp.w R13,R12
00802A 3BFB jl 0x8022
for(i = 0 ; i < n ; ++i)
00802C 430C clr.w R12
00802E 425E 8001 mov.b &n,R14
008032 3C05 jmp 0x803E
++LICZV[VDIOD[i]]; // po tych operacjach LICZV[i] będzie
zawierała
008034 4C5F 1100 mov.b 0x1100(R12),R15
008038 53DF 111E inc.b 0x111E(R15)
for(i = 0 ; i < n ; ++i)
00803C 531C inc.w R12
for(i = 0 ; i < n ; ++i)
00803E 9E0C cmp.w R14,R12
008040 3BF9 jl 0x8034
for(i = 1 ; i < k ; ++i)
008042 431C mov.w #0x1,R12
008044 3C04 jmp 0x804E
LICZV[i] += LICZV[i-1]; // teraz LICZV[i] zawiera pozycje w
posortowanej
008046 5CDC 111D 111E add.b 0x111D(R12),0x111E(R12)
for(i = 1 ; i < k ; ++i)
00804C 531C inc.w R12
for(i = 1 ; i < k ; ++i)
00804E 9D0C cmp.w R13,R12
008050 3BFA jl 0x8046
for(i = n-1 ; i >= 0 ; --i)
008052 4E0C mov.w R14,R12
008054 3C11 jmp 0x8078
j=--LICZV[VDIOD[i]]; // aktualizacja LICZV
008056 4C5E 1100 mov.b 0x1100(R12),R14
00805A 53FE 111E add.b #0xFF,0x111E(R14)
00805E 4E5F 111E mov.b 0x111E(R14),R15
VDOUT[j] = VDIOD[i]; //wstawienie elementu na odpowiednią
pozycję
008062 4ECF 1105 mov.b R14,0x1105(R15)
ADRDOUT[j][0] = ADRDIOD[i][0]; // sortowanie adresów
008066 5F0F rla.w R15
008068 4C0E mov.w R12,R14
00806A 5E0E rla.w R14
00806C 4EDF 110A 1114 mov.b 0x110A(R14),0x1114(R15)
ADRDOUT[j][1] = ADRDIOD[i][1]; // sortowanie adresów
008072 4EDF 110B 1115 mov.b 0x110B(R14),0x1115(R15)
for(i = n-1 ; i >= 0 ; --i)
008078 533C add.w #0xFFFF,R12
for(i = n-1 ; i >= 0 ; --i)
00807A 930C tst.w R12
00807C 37EC jge 0x8056
}
00807E 4130 ret
miłego analizowania.
K.
-
54. Data: 2014-04-06 13:43:03
Temat: Odp: Odp: Odp: Odp: C vs. ASM na przykładzie PIC18F
Od: Sylwester Łazar <i...@a...pl>
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.
-
55. Data: 2014-04-06 15:52:24
Temat: Re: Odp: Odp: C vs. ASM na przykładzie PIC18F
Od: janusz_k <J...@o...pl>
W dniu 05.04.2014 o 23:19 Sylwester Łazar <i...@a...pl> pisze:
>>> W ATMEGA są zdaje się instrukcje 16-bitowe.
>> tak
>>> W takim razie oznacza to, że jest <66 instrukcji?
>> 65
>
> Dzięki. Dobra robota.
> Podoba mi się ten ATMEGA32 (jak na 8-bitowca)
> Ma fajne instrukcje:
Te instrukcje mają wszystkie od najmniejszej tiny za 2,64zł :)
i pewnie 64bajty ram by wystarczyło na to sortowanie.
A na trochę więcej to masz Atmega88 nowy produkowany i kosztuje 6.14zł
no a potem to xmegi ,najtańsza D4 już za niecałe 9zł.
> W cyklach wychodzi C/ASM= 42/26=1,62
> Całkiem nieźle jak na razie. Nawet nie dwukrotna nadbudowa.
> 5) ATMEGA32 może pracować, jak dobrze wyczytałem @16MHz z czasem jednego
> cyklu: Tcy=1/16=62,5ns.
> Daje to obieg pętli:
> 42*62,5=2,625us
> Dla PICa 18F2320 @40MHz Tcy=1/40*4=100ns
> Daje to obieg pętli:
> 26*100= 2,6us
>
> I to jest ciekawa sprawa.
AVr został zooptymalizowany pod kompilatory dlatego produkują one dość
zwięzły kod no i sporo instrukcji jest w 1 cyklu wykonywane. Dlatego tak
dobry wynik.
> ==================================================
> ATMEGA32 z kompilatorem C (nie wiem jaka wersja?) Avr studio4
AVR studio4 z starym touchlanem GCC WinAVR-20100110.
Ale nowsze AvrStudio6.2 pewnie wyprodukuje podobny kod.
> Wykonuje tą samą funkcję, którą napisałem w ASM na PIC18 mniej więcej w
> tym
> samym czasie!
> Sukces polega zapewne na tym, że ATMEGA32 wydaje się dość zgrabnym
> maleństwem,
> a kompilator korzysta z listy rozkazów dość logicznie.
Zaletą ich seri jest wspólna lista rozkazów z malutkim wyjątkiem mnożenia,
reszta ta sama, różnią się tylko rom-em, ram-em i peryferiami.
> Oba procki mają tylko 3 rejestry indeksowe. Jeden więcej byłby w tym
> przypadku pomocny.
> ATMEGA32 jakieś 12-15 zł
> PIC18F2320 jakieś 20 -28 zł
> Polecam ATMEGA32 w takim razie, zarówno do pracy w ASM jak i w C.
> Choć zaznaczam, że na ATMEGA32 kawałka kodu jeszcze nie napisałem w ASM
> :-)
> Jednak, 8-bitowce to marne są,
Wszytko zależy do czego, do prostych sterowników w zupełności wystarczają.
A są już i takie gdzie spory program można zmieścić.
No i dużym plusem jest dobre darmowe środowisko AVRstudio.
--
Pozdr
Janusz
-
56. Data: 2014-04-06 16:28:10
Temat: Re: Odp: C vs. ASM na przykładzie PIC18F
Od: janusz_k <J...@o...pl>
W dniu 06.04.2014 o 00:47 Sylwester Łazar <i...@a...pl> pisze:
>> > ATMEGA32 jakieś 12-15 zł
>> > PIC18F2320 jakieś 20 -28 zł
>> > Polecam ATMEGA32 w takim razie, zarówno do pracy w ASM jak i w C.
>>
>> Ja bym go nie polecał bo ten procek znika z rynku. Jeśli już to jakiś
>> zamiennik np Atmega328. A tak w ogóle po co kupować 8 bitowy procek z
>> 1kB RAM za 12-15 zł gdy można kupić 32 bitowy z 8kB RAM za 7 zł?
>>
> http://www.tme.eu/pl/details/lpc1114fbd48_302/mikrok
ontrolery-nxp-arm/nxp/#
>> --
>> pozdrawiam
>> MD
> Z tych dwóch. Poniżej napisałem o 32 bitowym 32MX2xx.
> O.K.
> Wygląda, że 8-bitowce się kończą.
> Ale zawsze mogą służyć za PORT EXPANDER.
> Jeśli będzie w cenie takiej co CD4094, to można kupić takiego 8-bitowca i
> jeszcze sobie,
> do płytki piny dostosować :-)
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.
test6.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000000 00800100 0000013c 000001d0 2**0
CONTENTS, ALLOC, LOAD, DATA
1 .text 0000013c 00000000 00000000 00000094 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .bss 00000023 00800100 00800100 000001d0 2**0
ALLOC
3 .comment 00000030 00000000 00000000 000001d0 2**0
CONTENTS, READONLY
4 .debug_aranges 00000028 00000000 00000000 00000200 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_info 0000016e 00000000 00000000 00000228 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_abbrev 0000009b 00000000 00000000 00000396 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_line 00000096 00000000 00000000 00000431 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_frame 00000034 00000000 00000000 000004c8 2**2
CONTENTS, READONLY, DEBUGGING
9 .debug_str 00000129 00000000 00000000 000004fc 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_loc 00000094 00000000 00000000 00000625 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_ranges 00000018 00000000 00000000 000006b9 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 19 c0 rjmp .+50 ; 0x34 <__ctors_end>
2: 33 c0 rjmp .+102 ; 0x6a <__bad_interrupt>
4: 32 c0 rjmp .+100 ; 0x6a <__bad_interrupt>
6: 31 c0 rjmp .+98 ; 0x6a <__bad_interrupt>
8: 30 c0 rjmp .+96 ; 0x6a <__bad_interrupt>
a: 2f c0 rjmp .+94 ; 0x6a <__bad_interrupt>
c: 2e c0 rjmp .+92 ; 0x6a <__bad_interrupt>
e: 2d c0 rjmp .+90 ; 0x6a <__bad_interrupt>
10: 2c c0 rjmp .+88 ; 0x6a <__bad_interrupt>
12: 2b c0 rjmp .+86 ; 0x6a <__bad_interrupt>
14: 2a c0 rjmp .+84 ; 0x6a <__bad_interrupt>
16: 29 c0 rjmp .+82 ; 0x6a <__bad_interrupt>
18: 28 c0 rjmp .+80 ; 0x6a <__bad_interrupt>
1a: 27 c0 rjmp .+78 ; 0x6a <__bad_interrupt>
1c: 26 c0 rjmp .+76 ; 0x6a <__bad_interrupt>
1e: 25 c0 rjmp .+74 ; 0x6a <__bad_interrupt>
20: 24 c0 rjmp .+72 ; 0x6a <__bad_interrupt>
22: 23 c0 rjmp .+70 ; 0x6a <__bad_interrupt>
24: 22 c0 rjmp .+68 ; 0x6a <__bad_interrupt>
26: 21 c0 rjmp .+66 ; 0x6a <__bad_interrupt>
28: 20 c0 rjmp .+64 ; 0x6a <__bad_interrupt>
2a: 1f c0 rjmp .+62 ; 0x6a <__bad_interrupt>
2c: 1e c0 rjmp .+60 ; 0x6a <__bad_interrupt>
2e: 1d c0 rjmp .+58 ; 0x6a <__bad_interrupt>
30: 1c c0 rjmp .+56 ; 0x6a <__bad_interrupt>
32: 1b c0 rjmp .+54 ; 0x6a <__bad_interrupt>
00000034 <__ctors_end>:
34: 11 24 eor r1, r1
36: 1f be out 0x3f, r1 ; 63
38: cf ef ldi r28, 0xFF ; 255
3a: d4 e0 ldi r29, 0x04 ; 4
3c: de bf out 0x3e, r29 ; 62
3e: cd bf out 0x3d, r28 ; 61
00000040 <__do_copy_data>:
40: 11 e0 ldi r17, 0x01 ; 1
42: a0 e0 ldi r26, 0x00 ; 0
44: b1 e0 ldi r27, 0x01 ; 1
46: ec e3 ldi r30, 0x3C ; 60
48: f1 e0 ldi r31, 0x01 ; 1
4a: 02 c0 rjmp .+4 ; 0x50 <__do_copy_data+0x10>
4c: 05 90 lpm r0, Z+
4e: 0d 92 st X+, r0
50: a0 30 cpi r26, 0x00 ; 0
52: b1 07 cpc r27, r17
54: d9 f7 brne .-10 ; 0x4c <__do_copy_data+0xc>
00000056 <__do_clear_bss>:
56: 21 e0 ldi r18, 0x01 ; 1
58: a0 e0 ldi r26, 0x00 ; 0
5a: b1 e0 ldi r27, 0x01 ; 1
5c: 01 c0 rjmp .+2 ; 0x60 <.do_clear_bss_start>
0000005e <.do_clear_bss_loop>:
5e: 1d 92 st X+, r1
00000060 <.do_clear_bss_start>:
60: a3 32 cpi r26, 0x23 ; 35
62: b2 07 cpc r27, r18
64: e1 f7 brne .-8 ; 0x5e <.do_clear_bss_loop>
66: 44 d0 rcall .+136 ; 0xf0 <main>
68: 67 c0 rjmp .+206 ; 0x138 <_exit>
0000006a <__bad_interrupt>:
6a: ca cf rjmp .-108 ; 0x0 <__vectors>
0000006c <zlicz>:
ADRDIOD[4][0]=2;
ADRDIOD[4][1]=1;
zlicz();
}
void zlicz(){
6c: ee e1 ldi r30, 0x1E ; 30
6e: f1 e0 ldi r31, 0x01 ; 1
char i; // zmienna pomocnicza
char j; // zmienna pomocnicza
for(i = 0 ; i < k ; ++i)
LICZV[i] = 0; // zerowanie tablicy
70: 11 92 st Z+, r1
void zlicz(){
char i; // zmienna pomocnicza
char j; // zmienna pomocnicza
for(i = 0 ; i < k ; ++i)
72: 81 e0 ldi r24, 0x01 ; 1
74: e5 32 cpi r30, 0x25 ; 37
76: f8 07 cpc r31, r24
78: d9 f7 brne .-10 ; 0x70 <zlicz+0x4>
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
void main (void){
VDIOD[0]=1;
f0: 81 e0 ldi r24, 0x01 ; 1
f2: 80 93 00 01 sts 0x0100, r24
VDIOD[1]=2;
f6: 92 e0 ldi r25, 0x02 ; 2
f8: 90 93 01 01 sts 0x0101, r25
VDIOD[2]=6;
fc: 26 e0 ldi r18, 0x06 ; 6
fe: 20 93 02 01 sts 0x0102, r18
VDIOD[3]=4;
102: 24 e0 ldi r18, 0x04 ; 4
104: 20 93 03 01 sts 0x0103, r18
VDIOD[4]=3;
108: 23 e0 ldi r18, 0x03 ; 3
10a: 20 93 04 01 sts 0x0104, r18
ADRDIOD[0][0]=1;
10e: 80 93 0f 01 sts 0x010F, r24
ADRDIOD[0][1]=0;
112: 10 92 10 01 sts 0x0110, r1
ADRDIOD[1][0]=1;
116: 80 93 11 01 sts 0x0111, r24
ADRDIOD[1][1]=1;
11a: 80 93 12 01 sts 0x0112, r24
ADRDIOD[2][0]=1;
11e: 80 93 13 01 sts 0x0113, r24
ADRDIOD[2][1]=2;
122: 90 93 14 01 sts 0x0114, r25
ADRDIOD[3][0]=2;
126: 90 93 15 01 sts 0x0115, r25
ADRDIOD[3][1]=0;
12a: 10 92 16 01 sts 0x0116, r1
ADRDIOD[4][0]=2;
12e: 90 93 17 01 sts 0x0117, r25
ADRDIOD[4][1]=1;
132: 80 93 18 01 sts 0x0118, r24
zlicz();
136: 9a df rcall .-204 ; 0x6c <zlicz>
00000138 <_exit>:
138: f8 94 cli
0000013a <__stop_program>:
13a: ff cf rjmp .-2 ; 0x13a <__stop_program>
--
Pozdr
Janusz
-
57. Data: 2014-04-06 17:56:41
Temat: Odp: Odp: C vs. ASM na przykładzie PIC18F
Od: Sylwester Łazar <i...@a...pl>
>Tu masz jkeszcze w najnowszym As6.2, co prawda dał trochę ostrzeżeń ale
>zrobione to jest na nową ATmega88.
OK. Dzięki.
33 instrukcje w pętli sortowania.
Czyli jedna mniej jeśli policzyłem poprawnie.
Tak czy inaczej 2,6us/pętlę.
S.
-
58. Data: 2014-04-08 19:51:38
Temat: Odp: C vs. ASM na przykładzie PIC18F
Od: Sylwester Łazar <i...@a...pl>
Zainteresowałem się analizą czasową i tak na szybko ją przeprowadziłem
jeszcze dla n=14 rekordów.
Oto wyniki dla n=5 i n=14
Liczba próbek n=5
Czas wykonywania C: 168 [us]
Czas wykonywania ASM: 54 [us]
Liczba instrukcji C: 1675
Liczba instrukcji ASM: 542
Tc/Ta 3,1 x
Liczba próbek n=14
Czas wykonywania C: 791 [us]
Czas wykonywania ASM: 150 [us]
Liczba instrukcji C: 3955
Liczba instrukcji ASM: 749
Tc/Ta 5,3 x
Wnioski:
Po zwiększenie liczby próbek: 2,80 x
Zwiększenie czasu dla ASM: 2,76 x
Zwiększenie czasu dla C: 4,7 x
Wniosek:
Czas rośnie wykładniczo wraz ze zwiększeniem liczbą próbek dla C.
4,7>2,76
Dla kodu ASM rośnie wolniej niż wzrost liczby próbek.
2,80<2,76
Pozwolenie sobie na kiepski kod dla dużej liczby danych skutkuje
wykładniczo zapotrzebowaniem na moc.