MSX Programming Languages Showdown

Página 2/6
1 | | 3 | 4 | 5 | 6

Por PingPong

Prophet (3898)

imagem de PingPong

16-09-2013, 09:27

Marq wrote:

I'm happy to see the topic sparked some discussion Smile And the test case, indeed, is a trivial one, but at least it tells a thing or two. Loops are so fundamental that if they are slow, probably everything else is, too. Need to try the Hisoft cross-compiler when I get the chance. SDCC isn't that bad after all: if you look at the code it seems to do silly things at times, but the overhead isn't that heavy compared to many other compilers tested here. There's a lot of good top-level optimization going on even if the Z80 code generator is quite lame.

I also started with SDCC, then moved to HiSoft when i realized that almost in all situations the latter does generate a way more efficent code ( in terms of speed ). So I'm a bit surprised that a very simple test like the nested loop is so slow

Por PingPong

Prophet (3898)

imagem de PingPong

16-09-2013, 09:30

Another test: try to swap the counters limit in loops. the outer set to 100, the inner to 10000.
I expect very different results, even if the number of iterations is the same. I also expect no valuable differences in asm code.

Por ARTRAG

Enlighted (6845)

imagem de ARTRAG

16-09-2013, 14:04

Actually I measured also the loading time as the timing is done in an external script in msxdos

Por Marq

Champion (387)

imagem de Marq

16-09-2013, 15:31

I haven't tested the Hisoft cross-compiler yet. The MSX (probably CP/M) version on the list is likely to be old and slow. Let's see if I can replicate Artrag's results.

Por MicroTech

Champion (385)

imagem de MicroTech

16-09-2013, 15:37

*** MSX-C v.1.20

#include 
#define JIFFY   0xFC9E

void testCode()
{
	unsigned int i,j,s;

	s = 0;
	for (i = 0; i < 10000; i++)
		for(j = 0; j < 100; j++)
			s++;
	printf("%d\n",s);
}

int main(_argc, _argv)
int _argc;
char **_argv;
{
	unsigned int *pJiffy, t0, t1;

	/* set vdp interrupt rate to 60Hz */
	wrtvdp((TINY) 9, rdvdp((TINY) 9) & 0xFD);

	/* wait for JIFFY to change */
	pJiffy = (unsigned int *) JIFFY;
	t0 = *pJiffy;
	while (t0 == *pJiffy)
		;

	/* go with test */
	testCode();

	/* stop counting time */
	t1 = *pJiffy;
	t0++;

	printf("%u vdp interrupt(s)\n", (unsigned int) (t1 - t0));
	return (OK);
}

I managed to measure execution time by counting vdp interrupts (more precise).
I used blueMSX in MSXTurboR configuration in Z80 mode and vdp at 60Hz.
I got 1212 vdp interrupts corresponding to approx. 20,2 seconds Hannibal

Por msxegor

Master (183)

imagem de msxegor

16-09-2013, 15:50

If you add #pragma nonrec - you will probably get another 4 or 5 seconds saved...
BTW, can anyone test Solid C with this test? I don't have any hardware running currently.

Por yzi

Champion (444)

imagem de yzi

16-09-2013, 20:12

Stupid question, but is Hitech C the same as Hisoft C?

Anyway, if you think C compiler x beats SDCC, please add your own test function so we can really have a compiler fight. Smile

Por ARTRAG

Enlighted (6845)

imagem de ARTRAG

16-09-2013, 20:35

I've adapted the test to Hitech C and it gives 24 seconds (1480 ticks)
Note that I'm cheating a bit as I've moved "i" from automatic to static ;-)
Without this trick the code takes about 30 seconds (as before)

#include 
#include 

unsigned int i;

void testCode(void) {
	register unsigned int j,s;
	s = 0;
	for (i=0;i<10000;i++)
	  for(j=0;j<100;j++)
	    s++;
	printf("%d\n",s);
}



#define JIFFY   0xFC9E
#define	di()	asm("	di")
#define	ei()	asm("	ei")

void wrtvdp(unsigned char reg, unsigned char data) {
	di();
    outp(0x99,data);
    outp(0x99,128 | reg);
    ei();

}

unsigned char rdvdp(unsigned char reg) {
	return *((unsigned char*)0xFFE7-8+reg);
}


int main(int _argc, char **_argv) {
	unsigned int *pJiffy, t0, t1;

	/* set vdp interrupt rate to 60Hz */
	wrtvdp(9,rdvdp((unsigned char)9) & 0xFD);

	/* wait for JIFFY to change */
	pJiffy = (unsigned int *) JIFFY;
	t0 = *pJiffy;
	while (t0 == *pJiffy)
		;

	/* go with test */
	testCode();

	/* stop counting time */
	t1 = *pJiffy;
	t0++;

	printf("%u vdp interrupt(s)\n", (unsigned int) (t1 - t0));
	printf("%u second(s)\n", (unsigned int) (t1 - t0)/60);
	return (1);
}

The corresponding ASM is:

    8   0000'                   _testCode:
    9   0000' FD E5             	push	iy
   10                           ;main.c: 8: register unsigned int j,s;
   11                           ; _s allocated to iy
   12   0002' FD 21 0000        	ld	iy,0
   13                           ;main.c: 10: for (i=0;i<10000;i++)
   14   0006' 21 0000           	ld	hl,0
   15   0009' 18 14             	jp	L1
   16                           
   17   000B'                   l5:
   18                           ;main.c: 11: for(j=0;j<100;j++)
   19                           ; _j allocated to bc
   20   000B' 01 0000           	ld	bc,0
   21   000E'                   l9:
   22                           ;main.c: 12: s++;
   23   000E' FD 23             	inc	iy
   24   0010' 03                	inc	bc
   25   0011' 11 0064           	ld	de,064h
   26   0014' 69                	ld	l,c
   27   0015' 60                	ld	h,b
   28   0016' B7                	or	a
   29   0017' ED 52             	sbc	hl,de
   30   0019' 38 F3             	jp	c,l9
   31   001B' 2A 0000'          	ld	hl,(_i)
   32   001E' 23                	inc	hl
   33   001F'                   L1:
   34   001F' 22 0000'          	ld	(_i),hl
   35   0022' 01 2710           	ld	bc,02710h
   36   0025' B7                	or	a
   37   0026' ED 42             	sbc	hl,bc
   38   0028' 38 E1             	jp	c,l5
   39                           ;main.c: 13: printf("%d\n",s);
   40   002A' FD E5             	push	iy
   41   002C' 21 0000'          	ld	hl,u19
   42   002F' E5                	push	hl
   43   0030' CD 0000*          	call	_printf
   44   0033' C1                	pop	bc
   45   0034' C1                	pop	bc
   46                           ;main.c: 14: }
   47   0035' FD E1             	pop	iy
   48   0037' C9                	ret	
[...]
  141   0000'                   	psect	bss,class=DATA
  142   0000'                   _i:
  143   0000'                   	defs	2
  144   00D5'                   	psect		text

Por Marq

Champion (387)

imagem de Marq

16-09-2013, 23:59

Here's SDCC's view on the same:

   0000                      47 _main_start::
   0000                      48 _main:
   0000 DD E5                49 	push	ix
   0002 DD 21 00 00          50 	ld	ix,#0
   0006 DD 39                51 	add	ix,sp
   0008 F5                   52 	push	af
                             53 ;bensmark.c:5: int sum=0,i,j;
   0009 11 00 00             54 	ld	de,#0x0000
                             55 ;bensmark.c:7: for(i=0;i<10000;i++)
   000C DD 36 FE 00          56 	ld	-2 (ix),#0x00
   0010 DD 36 FF 00          57 	ld	-1 (ix),#0x00
   0014                      58 00104$:
   0014 DD 7E FE             59 	ld	a,-2 (ix)
   0017 D6 10                60 	sub	a,#0x10
   0019 DD 7E FF             61 	ld	a,-1 (ix)
   001C DE 27                62 	sbc	a,#0x27
   001E F2r38s00             63 	jp	P,00107$
                             64 ;bensmark.c:9: for(j=0;j<100;j++)
   0021 4B                   65 	ld	c,e
   0022 42                   66 	ld	b,d
   0023 11 64 00             67 	ld	de,#0x0064
   0026                      68 00103$:
                             69 ;bensmark.c:10: sum++;
   0026 03                   70 	inc	bc
   0027 1B                   71 	dec	de
                             72 ;bensmark.c:9: for(j=0;j<100;j++)
   0028 7B                   73 	ld	a,e
   0029 B2                   74 	or	a,d
   002A 20 FA                75 	jr	NZ,00103$
                             76 ;bensmark.c:7: for(i=0;i<10000;i++)
   002C 59                   77 	ld	e,c
   002D 50                   78 	ld	d,b
   002E DD 34 FE             79 	inc	-2 (ix)
   0031 20 03                80 	jr	NZ,00116$
   0033 DD 34 FF             81 	inc	-1 (ix)
   0036                      82 00116$:
   0036 18 DC                83 	jr	00104$
   0038                      84 00107$:
                             85 ;bensmark.c:13: printf("%d\r\n",sum);
   0038 D5                   86 	push	de
   0039 21r47s00             87 	ld	hl,#__str_0
   003C E5                   88 	push	hl
   003D CDr00s00             89 	call	_printf
   0040 F1                   90 	pop	af
   0041 F1                   91 	pop	af
   0042 DD F9                92 	ld	sp,ix
   0044 DD E1                93 	pop	ix
   0046 C9                   94 	ret
   0047                      95 _main_end::
   0047                      96 __str_0:
   0047 25 64                97 	.ascii "%d"
   0049 0D                   98 	.db 0x0D
   004A 0A                   99 	.db 0x0A
   004B 00                  100 	.db 0x00

Por Marq

Champion (387)

imagem de Marq

17-09-2013, 00:07

Looking at that the inner loop - which is the only thing that matters - doesn't look that bad at all:

loop:   inc bc
        dec de
        ld a,e
        or a,d
        jr nz,loop

I wish SDCC was always this smart Smile At times it does really bogus bouncing of values back and forth between registers.

Página 2/6
1 | | 3 | 4 | 5 | 6