[#1] Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira
Witam!

Nie jestem generalnie programistą, w C dłubię sobie okazyjnie prymitywne rzeczy. Assemblera nie znam, ale po obejrzeniu wykładu Cahira postanowiłem zbadać pewien problem, mianowicie, kopiowanie 1MB funkcją memcpy na 68000 (nie wiem jak na innych) trwa dłużej niż wczytanie takiego pliku z dysku do RAM przy transferze 1.6MB/s. To mnie zmusiło do sprawdzenia innych metod, jak poniższa pętla, które też szybkością nie grzeszyły. Gdyby nie Cahir, nie przyszło by mi do głowy, aby przejrzeć assember wygenerowany przez VBCC, w tym przypadku wykład przyniósł więc owoce.

O tej pętli już wspominałem w komentarzach pod newsem, ale wkleję ja jeszcze raz z przykładowym assemblerem generowanym przez VBCC 0.9d:

void memcpy_fast( UBYTE *dest,  UBYTE *src, ULONG size){
	while (size--) {
	*dest++ = *src++;
	
}


Powyższy kod przy kompilacji bez parametru optymalizacji (chyba -O=1 jest wtedy domyślne), generuje 9 instrukcji:

_memcpy_fast
	movem.l	l60,-(a7)
	move.l	(8+l62,a7),a3
	move.l	(4+l62,a7),a2
	move.l	(12+l62,a7),d1
	bra	l58
l57
	move.l	a3,a0
	addq.l	#1,a3
	move.l	a2,a1
	addq.l	#1,a2
	move.b	(a0),(a1)
l58
	move.l	d1,d0
	subq.l	#1,d1
	tst.l	d0
	bne	l57
l59
l56
l60	reg	a2/a3
	movem.l	(a7)+,a2/a3
l62	equ	8
	rts


O2 - 11! instrukcji
l57
	move.l	(24+l62,a7),(4+l62,a7)
	addq.l	#1,(24+l62,a7)
	move.l	(20+l62,a7),(8+l62,a7)
	addq.l	#1,(20+l62,a7)
	move.l	(4+l62,a7),a0
	move.l	(8+l62,a7),a1
	move.b	(a0),(a1)
	move.l	(28+l62,a7),(12+l62,a7)
	subq.l	#1,(28+l62,a7)
	tst.l	(12+l62,a7)
	bne	l57



Po sprowadzeniu pętli do wersji dla dzieci, czyli "kroczek po kroczku":

while (size) {
	*dest = *src;
	src++; dest++;
	size--;	
	}


Otrzymuję w przypadku:

-O=1
l57
	move.b	(a1)+,(a0)+
	subq.l	#1,d0
l58
	tst.l	d0
	bne	l57


-O=2
l57
	move.l	(8+l62,a7),a0
	move.l	(4+l62,a7),a1
	move.b	(a0),(a1)
	addq.l	#1,(8+l62,a7)
	addq.l	#1,(4+l62,a7)
	subq.l	#1,(12+l62,a7)
	bne	l57


-O=3
l60
	move.b	(a1)+,(a0)+
	subq.l	#1,d0
	bne	l60



Przeklejem wypowiedzi z komentarzy:


MR.SHULTZ:

Co ciekawe gcc5 i gcc6 generuja dosc zabawny kod. Przetestowalem 3 rozne wersje petli:

while(size--) {
    *dst++ = *src++;
}

while(size) {
    *dst = *src;
    dst++; src++; size--;
}

do {
    *dst++ = *src++;
} while(--size);



po skompilowaniu z -O2 -m68020 otrzymalem nastepujacy kod (tylko glowna petla):

.L3:
	move.l (%a1)+,(%a0)+
	dbra %d0,.L3
	clr.w %d0
	subq.l #1,%d0
	jcc .L3

.L9:
	move.l (%a1)+,(%a0)+
	subq.l #1,%d0
	jne .L9

.L14:
	move.l (%a1)+,(%a0)+
	subq.l #1,%d0
	jne .L14




-O1 dalo tak samo optymalny kod dla wszystkich trzech petli. Wniosek - nie zawsze O2 jest jepsze... ;)


CAHIR:
Trzeba przyznać, że poniższa wersja jest naprawdę dobra. Na slajdach dla zmiennej size użyłem typu WORD (aka signed short) stąd mogła wskoczyć optymalizacja z dbra. W tym kawałku kodu kompilator ładnie uogólnił optymalizację dla signed int.

.L3:
	move.l (%a1)+,(%a0)+ # ta pętla wykona się max. 65536 razy
	dbra %d0,.L3
	clr.w %d0            # ta część wykona się (size / 65536) razy, więc się nie liczy
	subq.l #1,%d0
	jcc .L3



Jak potrzebujecie więcej plików do testów to polecam funkcje biblioteki standardowej języka C ze źródeł systemu OpenBSD. Gdybyś ktoś z Was miał czas oraz chęci przedstawić i porównać działanie optymalizacji z VBCC vs. GCC 6.2 byłbym wdzięczny. Zapewne miażdżącą przewagę będzie miał GCC, ale trzeba to pokazać.

----------------------


Mam nadzieję, że ten wątek przyda się do zamieszczania przykładów sytuacji, w których trzeba kompilatorowi tłumaczyć co ma robić w języku "Kalego"


Cahir, mógłbyś przepisać ewolucję pętli z prezentacji? Nie specjalnie widać tam co piszesz.




Ostatnia aktualizacja: 15.12.2016 19:10:06 przez sanjyuubi
[#2] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #1

Zdaje się, że ewolucja wyglądała tak:

#include <exec/types.h>

void memcopy_0(LONG *src, LONG *dst, WORD n) {
  WORD i;
  for (i = 0; i < n; i++) {
    dst[i] = src[i];
  }
}

__regargs void memcopy_1(LONG *src, LONG *dst, WORD n) {
  WORD i;

  for (i = 0; i < n; i++) {
    *dst++ = *src++;
  }
}

__regargs void memcopy_2(LONG *src, LONG *dst, WORD n) {
  while (n--) {
    *dst++ = *src++;
  }
}

Kompilator będzie się inaczej zachowywał jeśli zamiast WORD n dasz LONG n i od razu wygeneruje "optymalną" wersję pętli. Dyrektywa __regargs jest specyficzna dla gcc-amigaos. Kompilowałem z -O2 -fomit-frame-pointer.
[#3] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #2

Zamieszczam kilka procedurek do porównywania kompilatorów:

#include <sys/types.h>

int memcmp(const void *s1, const void *s2, size_t n) {
  if (n != 0) {
    const unsigned char *p1 = s1, *p2 = s2;

    do {
      if (*p1++ != *p2++)
        return (*--p1 - *--p2);
    } while (--n != 0);
  }
  return 0;
}


int ffs(int mask) {
  int bit;
  unsigned r = mask;
  static const int t[16] = { -28, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1 };

  bit = 0;
  if ((r & 0xffff) == 0) {
    bit += 16;
    r >>= 16;
  }
  if ((r & 0xff) == 0) {
    bit += 8;
    r >>= 8;
  }
  if ((r & 0xf) == 0) {
    bit += 4;
    r >>= 4;
  }

  return (bit + t[r & 0xf]);
}


#include <sys/types.h>

size_t strlcpy(char *dst, const char *src, size_t siz) {
  char *d = dst;
  const char *s = src;
  size_t n = siz;

  /* Copy as many bytes as will fit */
  if (n != 0) {
    while (--n != 0) {
      if ((*d++ = *s++) == '\0')
        break;
    }
  }

  /* Not enough room in dst, add NUL and traverse rest of src */
  if (n == 0) {
    if (siz != 0)
      *d = '\0';    /* NUL-terminate dst */
    while (*s++)
      ;
  }

  return(s - src - 1);  /* count does not include NUL */
}


#include <stddef.h>

char *strsep(char **stringp, const char *delim) {
  char *s;
  const char *spanp;
  char c, sc;
  char *tok;

  if ((s = *stringp) == NULL)
    return NULL;
  for (tok = s;;) {
    c = *s++;
    spanp = delim;
    do {
      if ((sc = *spanp++) == c) {
        if (c == 0)
          s = NULL;
        else
          s[-1] = 0;
        *stringp = s;
        return tok;
      }
    } while (sc != 0);
  }
}
[#4] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #3

VBCC wygląda chyba zbyt biednie pod względem mnogości konfiguracji kompilacji pod GCC.

Taki oto kod wygenerował mi VBCC 0.9d z twoich przykładów, optymalizacja -O=3 (plik z O2 i O1 ma około 250 linii w porównaniu do O3 - 190 linii

idnt	"test.c"
	opt	0
	opt	NQLPSMRBT
	section	"CODE",code
	public	_memcmp
	cnop	0,4
_memcmp
	movem.l	l11,-(a7)
	move.l	(12+l13,a7),d0
	beq	l10
	move.l	(4+l13,a7),a3
	move.l	(8+l13,a7),a2
l9
	move.l	a3,a1
	addq.l	#1,a3
	move.l	a2,a0
	addq.l	#1,a2
	move.l	d0,(12+l13,a7)
	move.b	(a1),d1
	cmp.b	(a0),d1
	beq	l8
	moveq	#0,d1
	move.b	-(a3),d1
	moveq	#0,d0
	move.b	-(a2),d0
	neg.l	d0
	add.l	d1,d0
	bra	l1
l8
	subq.l	#1,d0
	bne	l9
l10
	moveq	#0,d0
l1
l11	reg	a2/a3
	movem.l	(a7)+,a2/a3
l13	equ	8
	rts
; stacksize=8
	opt	0
	opt	NQLPSMRBT
	public	_ffs
	cnop	0,4
_ffs
	movem.l	l22,-(a7)
	move.l	(4+l24,a7),d1
	moveq	#0,d2
	move.l	#65535,d0
	and.l	d1,d0
	bne	l17
	add.l	#16,d2
	moveq	#16,d0
	lsr.l	d0,d1
l17
	move.l	#255,d0
	and.l	d1,d0
	bne	l19
	addq.l	#8,d2
	lsr.l	#8,d1
l19
	moveq	#15,d0
	and.l	d1,d0
	bne	l21
	addq.l	#4,d2
	lsr.l	#4,d1
l21
	moveq	#15,d0
	and.l	d1,d0
	lsl.l	#2,d0
	lea	l15,a0
	add.l	d0,a0
	move.l	d2,d0
	add.l	(a0),d0
l22	reg	d2
	movem.l	(a7)+,d2
l24	equ	4
	rts
; stacksize=4
	cnop	0,4
l15
	dc.l	-28
	dc.l	1
	dc.l	2
	dc.l	1
	dc.l	3
	dc.l	1
	dc.l	2
	dc.l	1
	dc.l	4
	dc.l	1
	dc.l	2
	dc.l	1
	dc.l	3
	dc.l	1
	dc.l	2
	dc.l	1
	opt	0
	opt	NQLPSMRBT
	public	_strlcpy
	cnop	0,4
_strlcpy
	movem.l	l44,-(a7)
	move.l	(12+l46,a7),d1
	move.l	(4+l46,a7),a3
	move.l	(8+l46,a7),a2
	move.l	d1,d0
	beq	l42
	subq.l	#1,d0
	beq	l42
l40
	move.l	a2,a1
	addq.l	#1,a2
	move.l	a3,a0
	addq.l	#1,a3
	move.b	(a1),(a0)
	beq	l42
	subq.l	#1,d0
	bne	l40
l42
	tst.l	d0
	bne	l43
	tst.l	d1
	beq	l36
	move.b	#0,(a3)
l36
	move.l	a2,a0
	addq.l	#1,a2
	tst.b	(a0)
	beq	l43
l41
	move.l	a2,a0
	addq.l	#1,a2
	tst.b	(a0)
	bne	l41
l43
	move.l	a2,d0
	sub.l	(8+l46,a7),d0
	subq.l	#1,d0
l44	reg	a2/a3
	movem.l	(a7)+,a2/a3
l46	equ	8
	rts
; stacksize=8
	opt	0
	opt	NQLPSMRBT
	public	_strsep
	cnop	0,4
_strsep
	movem.l	l66,-(a7)
	move.l	(8+l68,a7),a5
	move.l	(4+l68,a7),a3
	move.l	(a3),a1
	move.l	a1,d2
	bne	l49
	moveq	#0,d0
	bra	l64
l49
	move.l	a1,a4
l62
	move.l	a1,a0
	addq.l	#1,a1
	move.b	(a0),d0
	move.l	a5,a2
l63
	move.l	a2,a0
	addq.l	#1,a2
	move.b	(a0),d1
	cmp.b	d1,d0
	bne	l58
	tst.b	d0
	bne	l60
	move.l	#0,a1
	bra	l61
l60
	move.b	#0,(-1,a1)
l61
	move.l	a1,(a3)
	move.l	a4,d0
	bra	l64
l58
	tst.b	d1
	bne	l63
	bra	l62
l64
l66	reg	a2/a3/a4/a5/d2
	movem.l	(a7)+,a2/a3/a4/a5/d2
l68	equ	20
	rts
; stacksize=20
[#5] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #4

Kompilowane moim toolchainem (tj. gcc 2.95.3) z opcjami "-O2 -m68000 -fomit-frame-pointer":

_memcmp:
	movel d2,sp@-
	movel sp@(16),d1
	jeq L3
	movel sp@(8),a0
	movel sp@(12),a1
	moveq #0,d2
	moveq #0,d0
L8:
	cmpmb a1@+,a0@+
	jeq L6
	moveb a0@(-1),d2
	moveb a1@(-1),d0
	subl d0,d2
	movel d2,d0
	jra L9
L6:
	subql #1,d1
	jne L8
L3:
	moveq #0,d0
L9:
	movel sp@+,d2
	rts

_t.3:
	.long -28
	.long 1
	.long 2
	.long 1
	.long 3
	.long 1
	.long 2
	.long 1
	.long 4
	.long 1
	.long 2
	.long 1
	.long 3
	.long 1
	.long 2
	.long 1

_ffs:
	movel d2,sp@-
	movel sp@(8),d1
	subl a1,a1
	tstw d1
	jne L3
	movew #16,a1
	clrw d1
	swap d1
L3:
	tstb d1
	jne L4
	addql #8,a1
	lsrl #8,d1
L4:
	movel d1,d0
	moveq #15,d2
	andl d2,d0
	jne L5
	addql #4,a1
	lsrl #4,d1
L5:
	moveq #15,d0
	andl d0,d1
	lsll #2,d1
	lea (_t.3),a0
	movel a1,d0
	addl a0@(d1:l),d0
	movel sp@+,d2
	rts

_strlcpy:
	movel d2,sp@-
	movel sp@(12),d2
	movel sp@(16),d1
	movel sp@(8),a1
	movel d2,a0
	movel d1,d0
	jeq L12
L7:
	subql #1,d0
	jeq L13
	moveb a0@+,a1@
	tstb a1@+
	jne L7
	jra L8
L13:
	tstl d1
	jeq L12
	clrb a1@
L12:
	tstb a0@+
	jne L12
L8:
	subl d2,a0
	movel a0,d0
	subql #1,d0
	movel sp@+,d2
	rts

_strsep:
	moveml d2/d3/a2,sp@-
	movel sp@(16),a2
	movel sp@(20),d3
	movel a2@,a0
	cmpw #0,a0
	jne L3
	moveq #0,d0
	jra L14
L3:
	movel a0,d2
L4:
	moveb a0@+,d0
	movel d3,a1
L13:
	moveb a1@+,d1
	cmpb d1,d0
	jne L9
	tstb d1
	jne L11
	subl a0,a0
	jra L12
L11:
	clrb a0@(-1)
L12:
	movel a0,a2@
	movel d2,d0
	jra L14
L9:
	tstb d1
	jne L13
	jra L4
L14:
	moveml sp@+,d2/d3/a2
	rts


Ostatnia aktualizacja: 16.12.2016 09:03:43 przez cahir
[#6] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #5

Prócz tego, że kod jest mniejszy, wygląda na to, że mechanika analizy kontekstu jest w przypadku GCC lepsza, gdzie w funkcji ffs kompilator zauważył, że zmienna r będzie zawsze miała 0x0000 w najmłodszym słowie, a wiec po przesunięciu 16bitów w prawo 0xXXXX0000 będzie zawsze miało postać 0x0000XXXX i zastosowało instrukcję swap.

Do kodowania więc VBCC się chyba specjalnie nie nadaje, ciekawe czy VBCC "łyknęłoby" twoje idiomy z prezentacji.
[#7] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #1

fajna analiza ale bez benchmarków nie daje pelnego obrazu
[#8] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@XoR, post #7

Nie trzeba robić benchmarków, żeby udowodnić, że pętla z 3 instrukcji będzie szybsza niż z 9.

Cahir na wykładzie dał do zrozumienia, że zabiera się się za optymalizacje, gdy coś się nie wyrabia i wtedy znajomość kompilatora pozwala na uniknięcie generowania assemblerowego bełkotu. Przydatne, gdy robi się ciasno.
[#9] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #8

Znalazłem GCC 5.2.0 skompilowane już dla windows i ta pętla

void memcpy_fast( ULONG *dest,  ULONG *src, ULONG size){
	size=size/4;
	
while (size--) {
	*dest++ = *src++;	
	}


już przy O1 dała taki kod:

memcpy_fast:
	link.w %fp,#0
	move.l 12(%fp),%a0
	move.l 16(%fp),%d1
	lsr.l #2,%d1
	move.l %d1,%d0
	subq.l #1,%d0
	tst.l %d1
	jeq .L5
	move.l 8(%fp),%a1
.L7:
	move.l (%a0)+,(%a1)+
	dbra %d0,.L7
	clr.w %d0
	subq.l #1,%d0
	jcc .L7
.L5:
	unlk %fp
	rts


Nawet nie trzeba używać WORD dla zmiennej size.
[#10] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #5

No to przy okazji znalezienia GCC 5.2.0 skompilowałem ci te przykłady z tymi samymi parametrami, sam powiedz, czy wyszło gorzej czy lepiej, bo ja tu robię tylko za kompiluj&wklej :)

#NO_APP
	.file	"test.c"
	.text
	.align	2
	.globl	memcmp
	.type	memcmp, @function
memcmp:
	move.l %d2,-(%sp)
	move.l 8(%sp),%a1
	move.l 12(%sp),%a0
	move.l 16(%sp),%d0
	jeq .L5
.L4:
	move.b (%a1)+,%d1
	move.b (%a0)+,%d2
	cmp.b %d1,%d2
	jne .L9
	subq.l #1,%d0
	jne .L4
	move.l (%sp)+,%d2
	rts
.L5:
	moveq #0,%d0
	move.l (%sp)+,%d2
	rts
.L9:
	moveq #0,%d0
	move.b %d1,%d0
	and.l #255,%d2
	sub.l %d2,%d0
	move.l (%sp)+,%d2
	rts
	.size	memcmp, .-memcmp
	.align	2
	.globl	ffs
	.type	ffs, @function
ffs:
	move.l %d2,-(%sp)
	move.l 8(%sp),%d2
	tst.w %d2
	jne .L14
	clr.w %d2
	swap %d2
	moveq #16,%d0
.L11:
	tst.b %d2
	jne .L12
	addq.l #8,%d0
	lsr.l #8,%d2
.L12:
	moveq #15,%d1
	and.l %d2,%d1
	jne .L13
	addq.l #4,%d0
	move.l %d2,%d1
	lsr.l #4,%d1
	moveq #15,%d2
	and.l %d2,%d1
.L13:
	add.l %d1,%d1
	add.l %d1,%d1
	lea t.1549,%a0
	add.l (%a0,%d1.l),%d0
	move.l (%sp)+,%d2
	rts
.L14:
	moveq #0,%d0
	jra .L11
	.size	ffs, .-ffs
	.align	2
	.globl	strlcpy
	.type	strlcpy, @function
strlcpy:
	move.l %a2,-(%sp)
	move.l 12(%sp),%d1
	move.l 16(%sp),%a0
	cmp.w #0,%a0
	jeq .L24
	move.l 8(%sp),%a1
	lea -1(%a1,%a0.l),%a2
	move.l %d1,%a0
.L19:
	cmp.l %a2,%a1
	jeq .L35
	move.b (%a0)+,%d0
	move.b %d0,(%a1)+
	jne .L19
.L20:
	sub.l %d1,%a0
	move.l %a0,%d0
	subq.l #1,%d0
	move.l (%sp)+,%a2
	rts
.L24:
	move.l %d1,%a0
.L23:
	tst.b (%a0)+
	jeq .L20
.L34:
	tst.b (%a0)+
	jne .L23
	jra .L20
.L35:
	clr.b (%a2)
	tst.b (%a0)+
	jne .L34
	jra .L20
	.size	strlcpy, .-strlcpy
	.align	2
	.globl	strsep
	.type	strsep, @function
strsep:
	movem.l #14368,-(%sp)
	move.l 20(%sp),%a2
	move.l 24(%sp),%d4
	move.l (%a2),%d0
	jeq .L42
	move.l %d0,%a1
	move.l %a1,%d3
	addq.l #1,%d3
	move.b (%a1),%d2
	move.l %d4,%a0
.L40:
	move.b (%a0)+,%d1
	cmp.b %d2,%d1
	jeq .L47
	tst.b %d1
	jne .L40
	move.l %d3,%a1
	move.l %a1,%d3
	addq.l #1,%d3
	move.b (%a1),%d2
	move.l %d4,%a0
	jra .L40
.L47:
	tst.b %d2
	jeq .L43
	clr.b (%a1)
	move.l %d3,(%a2)
.L37:
	movem.l (%sp)+,#1052
	rts
.L43:
	moveq #0,%d3
	move.l %d3,(%a2)
	jra .L37
.L42:
	moveq #0,%d0
	movem.l (%sp)+,#1052
	rts
	.size	strsep, .-strsep
	.section	.rodata
	.align	2
	.type	t.1549, @object
	.size	t.1549, 64
t.1549:
	.long	-28
	.long	1
	.long	2
	.long	1
	.long	3
	.long	1
	.long	2
	.long	1
	.long	4
	.long	1
	.long	2
	.long	1
	.long	3
	.long	1
	.long	2
	.long	1
	.ident	"GCC: (Tranaptic-2015/08/21-08:49:49) 5.2.0"
[#11] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #10

Przypomniało mi się że z VBCC warto dodać przełączniki -sc -sd, czyli small code i small data. I jak dobrze pamiętam to VBCC dbcc nie wygeneruje, no chyba że wstawke zrobić asemblerową.
A tak poza tym to okrutnie ciężko mi się czyta to co gcc wypluwa.
[#12] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@asman, post #11

Dodałem te przełączniki, ale i tak dostaję pętlę złożoną z 9 instrukcji.
[#13] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #12

@sanjyuubi: proszę podziel zrzut asemblerowy na osobne procedurki (z użyciem formatek forum), będzie się łatwiej czytać. Dodatkowo wytnij zbędne dyrektywy (np. .size, .object, itd.). I kompiluj koniecznie z jawnie podanymi flagami -O2 -m68000 -fomit-frame-pointer.

Ostatnia aktualizacja: 16.12.2016 21:13:10 przez cahir
[#14] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #9

Gdzie znalazłeś tak nowe gcc z targetem m68k-amigaos?

A wątek bardzo fajny, może w końcu skończy się cały bulszit o wyższości jednego kompilatora nad drugim i znajdzie się niekwestionowany zwycięzca.
[#15] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@asman, post #11

GCC ma odpowiedniki w postaci flag -msmall-code i -msmall-data. Powodują one odpowiednio wygenerowanie kodu, który:

  • używa trybu PC-relative do adresowania kodu i danych tylko do odczytu (sekcje .text, .rodata),
  • używa trybu baserel (z użyciem rejestru A4) do adresowania danych (połączone sekcje .data i .bss).

... to ogranicza kod i dane w naszym programie do 64KiB – natomiast nie ma większego wpływu na wydajność kodu.
[#16] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@teh_KaiN, post #14

To jest chyba tylko sam kompilator na windows, ale nie jestem pewien, bo trochę waży.

MinGW GCC For M68K



Ostatnia aktualizacja: 17.12.2016 06:44:04 przez sanjyuubi
[#17] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #13

Czy mam wycinać od nazwy etykiety do pierwszego wystąpienia RTS?
Takie flagi były ustawione w ostatnim przykładzie.
[#18] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #17

Od etykiety wyznaczającej początek procedury do ostatniego RTS przed wystąpieniem etykiety następnej procedury (zauważ, że procedura może mieć kilka punktów wyjścia).
[#19] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #16

W dystrybucji Debian Sid (unstable) i Stretch (testing) jest w chwili obecnej GCC 6.1 dla m68k. Zapewne w Ubuntu jest podobnie. Oczywiście jest to kompilator, który rozumie linuksowe (a nie amigowe) środowisko, tj. konwencję wołania procedur, wywołania biblioteczne itp.
[#20] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #19

A dałoby zmusić GCC żeby wypluwało kod źródłowy w formacie bardziej zrozumiałym dla mnie, tak by potem jakimś asemblerem - asm-one, basm, devpac, dało radę to skompilować ?
[#21] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@asman, post #20

Tutaj koleś skompilował gcc 6.2 m68k.
Niestety nie udostępnił binarki ale opisał co należy spaczować.

Ostatnia aktualizacja: 17.12.2016 22:17:58 przez Artur Jarosik
[#22] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@Artur Jarosik, post #21

Udało mi się skompilować m68k-elf-gcc v6.2.
Jutro zrobię testy a właściwie to dzisiaj.
[#23] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@Artur Jarosik, post #22

Ale ta wersja jest raczej mało użyteczna dla Amigi. Chyba że kawałki kodu będziesz disasemblował i wrzucał w asmie do programu kompilowanego GCC amigowym.
[#24] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@Krashan, post #23

https://github.com/bebbo/amigaos-cross-toolchain/blob/master/tools/elf2hunk.c
[#25] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@Artur Jarosik, post #24

ja tu regularnie pracuje z arosowym backendem 6.1.0 na m68k-elf spod linuxa. interesujace wiec jak sie sprawi w porownaniu ;)
[#26] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@cahir, post #18

OK.

Teraz na GCC 3.4.0 z AmiDevCpp

_memcmp:
	movel d2,sp@-
	movel sp@(16),d1
	jeq L2
	movel sp@(8),a0
	movel sp@(12),a1
	moveq #0,d2
	moveq #0,d0
	.even
L3:
	cmpmb a1@+,a0@+
	jne L8
	subql #1,d1
	jne L3
L2:
	moveq #0,d0
	jra L1
	.even
L8:
	moveb a0@(-1),d2
	moveb a1@(-1),d0
	subl d0,d2
	movel d2,d0
	.even
L1:
	movel sp@+,d2
	rts


t.0:
	.long	-28
	.long	1
	.long	2
	.long	1
	.long	3
	.long	1
	.long	2
	.long	1
	.long	4
	.long	1
	.long	2
	.long	1
	.long	3
	.long	1
	.long	2
	.long	1
	.even
	.globl	_ffs
_ffs:
	movel d2,sp@-
	movel sp@(8),d1
	moveq #0,d2
	tstw d1
	jne L10
	moveb #16,d2
	clrw d1
	swap d1
L10:
	tstb d1
	jne L11
	addql #8,d2
	lsrl #8,d1
L11:
	moveq #15,d0
	andl d1,d0
	jne L12
	addql #4,d2
	movel d1,d0
	lsrl #4,d0
	moveq #15,d1
	andl d1,d0
L12:
	lsll #2,d0
	lea (t.0),a0
	movel a0@(d0:l),d0
	addl d2,d0
	movel sp@+,d2
	rts


_strlcpy:
	movel d3,sp@-
	movel d2,sp@-
	movel sp@(16),d3
	movel sp@(20),d2
	movel sp@(12),a1
	movel d3,a0
	movel d2,d1
	jeq L15
	.even
L25:
	subql #1,d1
	jeq L15
	moveb a0@+,d0
	moveb d0,a1@+
	jne L25
	.even
L15:
	tstl d1
	jne L20
	tstl d2
	jeq L22
	clrb a1@
	.even
L22:
	tstb a0@+
	jne L22
L20:
	subl d3,a0
	movel a0,d0
	subql #1,d0
	movel sp@+,d2
	movel sp@+,d3
	rts


_strsep:
	moveml #0x3020,sp@-
	movel sp@(16),a2
	movel sp@(20),d2
	movel a2@,a1
	moveq #0,d0
	cmpw #0,a1
	jeq L27
	movel a1,d3
	.even
L29:
	moveb a1@+,d0
	movel d2,a0
	moveb a0@+,d1
	cmpb d1,d0
	jeq L39
	.even
L33:
	tstb d1
	jeq L29
	moveb a0@+,d1
	cmpb d1,d0
	jne L33
L39:
	tstb d1
	jne L35
	subl a1,a1
	movel a1,a2@
	movel d3,d0
	jra L27
	.even
L35:
	clrb a1@(-1)
	movel a1,a2@
	movel d3,d0
L27:
	moveml sp@+,#0x40c
	rts
[#27] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@Artur Jarosik, post #24

A da radę tym normalnie wygenerować plik wykonywalny dla AOS2.0+?
[#28] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@sanjyuubi, post #27

A da radę tym normalnie wygenerować plik wykonywalny dla AOS2.0+?


jezeli pedziesz kodowal w oparciu o naglowki do 2.0 to czemu nie? format hunk sam w sobie nie podlegl chyba zadnym zmianom?

narzedzie pochodzi zreszta z arosa. istnieje metoda wygenerowania ze zrodel arosa samego toolchaina 68k(ktora opisalem na sieci, moge podac link). w ten sposob powinno sie wlasciwie otrzymac backend ktorym moznaby kompilowac czy tez portowac inne zrodla, wystarczy uzywac amigoego ndk czy sdk czy jak to sie nazywa i linkowac przeciwko amigowym bibliotekom, a nastepnie skonwertowac binarki do hunka jak powyzej.

Ostatnia aktualizacja: 18.12.2016 03:07:51 przez wawrzon

Ostatnia aktualizacja: 18.12.2016 03:08:39 przez wawrzon
[#29] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@teh_KaiN, post #14

może w końcu skończy się cały bulszit o wyższości jednego kompilatora nad drugim i znajdzie się niekwestionowany zwycięzca


Jak dla mnie GCC jest lepsze niż VBCC, ten sam program skompilowany i zlinkowany pod VBCC zajmuje mi 17kB, a pod GCC 11kB. W dodatku nie muszę kombinować z sposobem zaprezentowania pętli, aby GCC wygenerowało zoptymalizowany kod w przeciwieństwie do VBCC.
[#30] Re: Z kompilatorem C jak z dzieckiem - optymalizacje, porównania, odniesienie do wykładu Cahira

@wawrzon, post #28

@wawrzon, byłbym wdzięczny za tego linka.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem