Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.
Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.
emka:
Całkowity czas wykonania programu wyniósł dla CC65 10.6s a dla ACTION'a 11,6s.emka:
Co do samego algorytmu to ograniczeniem ACTION'a jest maksymalna wielkość zmiennych WORD, a ograniczeniem CC65 jest pamięć komputera,BYTE RTCLOK2=19,RTCLOK3=20
BYTE ARRAY FLAGS(8192)
CARD COUNT,I,K,KROK
BYTE ARRAY MASK(8)=[1 2 4 8 16 32 64 128]
BYTE ARRAY MASKX(8)=[$FE $FD $FB $F7 $EF $DF $BF $7F]
PROC CLRX(CARD X)
BYTE Y
Y=X&7
X=X RSH 3
FLAGS(X)==& MASKX(Y)
RETURN
BYTE FUNC TESX(CARD X)
BYTE Y
Y=X & 7
X=X RSH 3
RETURN(FLAGS(X) & MASK(Y))
PROC SIEVE()
RTCLOK2=0
RTCLOK3=0
COUNT=1
FOR I=0 TO $1FFF
DO
FLAGS(I)=$AA
OD
FOR I=3 TO 255 STEP 2
DO
IF TESX(I) THEN
; PRINTF("%U ",I)
K=I*I
KROK=I+I
WHILE (K > KROK)
DO
CLRX(K)
K==+KROK
OD
FI
OD
FOR I=3 TO $FFFD STEP 2
DO
IF TESX(I) THEN
COUNT==+1
; PRINTF("%U ",I)
FI
OD
I=RTCLOK2*256+RTCLOK3
PRINTF("%E %U LICZB PIERWSZYCH W CZASIE",COUNT)
PRINTF("%E %U RAMEK",I)
RETURN
// cl65 -t atari -O sito.c -o sito.xex
#include <stdio.h>
#define RTCLOK2 *(unsigned char*)19
#define RTCLOK3 *(unsigned char*)20
unsigned int i,k,count,krok;
char mask[8]={1,2,4,8,16,32,64,128};
char maskx[8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
char flags[8192];
void main(void)
{
RTCLOK2=0;
RTCLOK3=0;
count=1;
for(i=0;i<8192;++i)
flags[i]=0xaa;
for(i=3;i<256;i+=2)
{
if (flags[i>>3] & mask[i&7])
{
// printf("%u ",i);
k=i*i;
krok=i+i;
while(k>=krok)
{
flags[k>>3] &= maskx[k&7];
k+=krok;
}
}
}
for(i=3;i>2;i+=2)
{
if (flags[i>>3] & mask[i&7])
{
++count;
// printf("%u ",i);
}
}
i=(RTCLOK2<<8)+RTCLOK3;
printf("%e %u liczb pierwszych w czasie\n ",count);
printf("%e %u ramek\n",i);
for (;;);
}
emka:
Wydaje mi się że oba testy napisane zostały w sposób maksymalnie wykorzystujący możliwości obu języków, ale pewnie tylko mi się wydaje.31 IF TESX(I) THEN
na IF (FLAGS(I RSH 3) & MASK(I & 7))THEN
37 CLRX(K)
na FLAGS(K RSH 3)==& MASKX(K&7)
47 IF TESX(I) THEN
na IF (FLAGS(I RSH 3) & MASK(I & 7))THEN
emka:
No i zaczęło się !emka:
nie ma sensu optymalizowanie kodu pod architekturę ATARIemka:
co do procedur i funkcji to można je włączyć w główną funkcje tak jak w CC65 (...)emka:
RSH jest wolne ale i tak jest to najszybsze dzielenieemka:
dzielenie ( w tym przypadku przez 8emka:
ależy również rozważyć to że zagnieżdżenie RSH wywoła procedurę biblioteczną która jest dopiero wolnaemka:
Temat traktuję edukacyjnieemka:
chyba że ktoś potrafi zoptymalizować ACTIONA! bez schodzenia do assembleratdc:
No i jakie są teraz wyniki szybkości ?tdc:
RSH zawsze wywołuje procedurę bibliotecznąx = x rsh 3 zostało zamienione na
lsr x+1
ror x
lsr x+1
ror x
lsr x+1
ror x
tdc:
skoro optymalizujesz to w C to w Action! musisz tym bardziejlda #$01
85 sta _i
A5 L0003: lda _i
F0 beq L0004
A2 ldx #$9C
A9 lda #$68
18 clc
65 adc _i
90 bcc L000E
E8 inx
85 L000E: sta sreg
86 stx sreg+1
A9 lda #$01
A0 ldy #$00
91 sta (sreg),y
E6 inc _i
4C jmp L0003
60 L0004: rts
lda #$01
sta L0004
L0005: lda L0004
beq L0006
ldy L0004
lda #$02
sta _a,y
inc L0004
jmp L0005
L0006: rts
ilmenit:
CC65 nie potrafi optymalizować kodu, gdy wskaźnik zdefiniujesz na stałe miejsce w pamięciunsigned char a[255];
unsigned int j;
unsigned char i;
void main(void)
{
for (i=1;i;++i)
a[j & 0xff] = 0x02;
}
otrzymamy taki kod
lda #$01
sta _i
L0003: lda _i
beq L0004
lda _j
clc
adc #<(_a)
sta ptr1
lda #$00
adc #>(_a)
sta ptr1+1
lda #$02
ldy #$00
sta (ptr1),y
inc _i
jmp L0003
L0004: rts
emka:
wykonanie programu w ACTION! wydłużyło się do 13semka:
Nie zawsze, akurat w procedurze clrx() i funkcji tesx()emka:
oba programy są identyczne w 99% i nieoptymalizowaneemka:
nie bardzo wiem co tu optymalizować nawet w maszynieemka:
Czy jest jakiś podręcznik optymalizacji do ACTION!a?ilmenit:
By jeszcze przyspieszyć można przenieść zmienne do main() i dać je jako "register".a[ (unsigned char) j ] = 0x02;
.proc _main: near
.segment "CODE"
;
; for (i=1;i;++i)
;
lda #$01
sta _i
L0004: lda _i
beq L0005
;
; a[ (unsigned char) j ] = 0x02;
;
ldy _j
lda #$02
sta _a,y
;
; for (i=1;i;++i)
;
inc _i
jmp L0004
;
; }
;
L0005: rts
tdc:
Jest to jasny dowód na to że Action! jest językiem do gier i dem a nie do obliczeńillmenit:
W C typy rzutuje się inaczejxxl:
gdyby kontrola znacznikow byla przeprowadzona to linia lda _i bylaby niepotrzebnaout rtclock1@20:byte
out rtclock2@19:byte
count:0..8191
const
mask:array(0..7) = 1,2,4,8,16,32,64,128
maskx:array(0..7) = %1111'1110,%1111'1101,%1111'1011,%1111'0111,%1110'1111,%1101'1111,%1011'1111,%0111'1111
flags:array(count)
rtclock1 = 0
rtclock2 = 0
for i:0..$1fff flags(i)=$aa
for i:3..255 step 2 where (flags(i/8) and mask(i mod 8) <> 0)
for k:i*i..8192 step 2*i
flags(k/8) = flags(k/8) and maskx(k mod 8)
count = 1
for k:3..8192 step 2 where (flags(k/8) and mask(k mod 8) <> 0)
inc count
t = rtclock2 * 256 + rtclock1
"[count] prime numbers in [t] ticks"
rudla:
Is that some trick with overflow?rule ifle %A,%B:card, %C:card = instr
let _a, %C(0) ; lda %B
sub _void, _a, %B(0) ; cmp %C
let _a, %C(1) ; lda %B+1
sub _void, _a, %B(1) ; cmp %C+1
ifeq %A, _C, 1 ; jcs %A
rule ifle %A,%B:card, %C:card = instr
let _a, %B(1) ; lda %B+1
sub _void, _a, %C(1) ; cmp #>%C
ifeq %A, _C, 0 ; bcc %1
ifeq _lab1, _Z, 0 ; beq _lab1
let _a, %B(0) ; lda %B
sub _void, _a, %C(0) ; cmp #<%C
ifeq %A, _C, 0 ; bcc %A
label _lab1
Od 1 do 34 z 34