About C / Z80 optimizations (SDCC)

Page 14/17
7 | 8 | 9 | 10 | 11 | 12 | 13 | | 15 | 16 | 17

By zPasi

Champion (472)

zPasi's picture

14-09-2019, 22:59

PingPong wrote:

It is always relevant. The time wasted in parameter passing is somewhat undesiderable. A sort of overhead.

Prove it.

Usually only very simple functions benefits register parameters. Others, like seen in the circle example, push the values into the stack anyway.

PingPong wrote:

Or do you think that a lot of impressive achievements on those 8 bit machines like speccy msx cpc c64 were obtained by wasting cpu cycles?

Not every game or utility have to be impressive. But even with SDCC it's possible to get pretty good results, when you know how to use it.

And every last cpu cycle is not always needed. Think a game like Tetris.

By Timmy

Expert (110)

Timmy's picture

15-09-2019, 02:07

PingPong wrote:

I never said that the spectrum is better or worse than msx.

You don't have to be modest, really. Smile You have spent numerous times saying how bad the MSX hardware is compared to the Spectrum hardware. If there was someone who puts the Spectrum first in this community, then it's you! <3

Quote:

And seeing your point of view about code optimization I suggest you to develop your programs with a i7 processor peraphs with some high level language like javascript or phython

Thanks! Right again! Of course I'm not developing my MSX programmes from a Spectrum. Obviously z88dk doesn't work on the Spectrum, I also use many tools in many languages. Even back in the days, many people don't develop on the same platform.

PS. I don't actually own an i7 computer. But I don't mind accepting donations. Wink

Quote:

Or do you think that a lot of impressive achievements on those 8 bit machines like speccy msx cpc c64 were obtained by wasting cpu cycles?

It doesn't really matter what I think, because 99% of the Spectrum games waste cpu cycles. But then again we were lucky that the Spectrum is the platform with the most text adventures. Smile

PingPong wrote:

It is always relevant. The time wasted in parameter passing is somewhat undesiderable. A sort of overhead. So minimizing it is desiderBle because it allows to use more effectively cpu time.

Again, you are really funny! Shocked! Now, I could explain here why having more effective cpu time is not relevant for making a good game, but instead I want to congratulate you for making me laughing out loud again!

I am really glad you are on this MSX community, and not somewhere else!

By PingPong

Prophet (3449)

PingPong's picture

15-09-2019, 06:17

[quote=Timmy wrote:
PingPong wrote:

I never said that the spectrum is better or worse than msx.

You don't have to be modest, really. Smile You have spent numerous times saying how bad the MSX hardware is compared to the Spectrum hardware. If there was someone who puts the Spectrum first in this community, then it's you! <3

prove that instead of saying blah blah,

Quote:
Quote:

And seeing your point of view about code optimization I suggest you to develop your programs with a i7 processor peraphs with some high level language like javascript or phython

PS. I don't actually own an i7 computer. But I don't mind accepting donations. Wink

donating a computer to you would be a total waste.

Or do you think that a lot of impressive achievements on those 8 bit machines like speccy msx cpc c64 were obtained by wasting cpu cycles?[/quo
[quote
wrote:

It doesn't really matter what I think, because 99% of the Spectrum games waste cpu cycles. But then again we were lucky that the Spectrum is the platform with the most text adventures. Smile

exact! "it does not really matter what you think". Because your thoughts are totally nonense.
About 99% of zx spectrum games waste cpu cycles PROVE THAT.
there are some games where in order to achieve great fps programmers made abuse of z80 stack for example, if your assumptions were correct why searching for any dirty way to speed up things when one can optmize so "wasted" cpu cycles?
It would be enough to optmize waste.

You really prove us that you do not know anything of the things you speak about.

your last post make you simply ridiculus.

By PingPong

Prophet (3449)

PingPong's picture

15-09-2019, 06:34

Quote:
zPasi wrote:
PingPong wrote:

It is always relevant. The time wasted in parameter passing is somewhat undesiderable. A sort of overhead.

Prove it.

no need to prove anything. it's a question of simple math.if my routine uses 40 t-cycles for the payload and an overhead of 80 t-cycles to manage stack frame and auto variables i have a kind of overhead. if the 80t-cycles could be reduce to say, 20 the overhead is more acceptable. ideally should be 0 .

And SDCC proved that is somewhat inefficient in doing this as is clear visible in one artag post about the status of sdcc in 2008. I do not know the present status by i cannot guess more better situation.

Try to code a simple vpeek / vpoke function (with 17 bit addressing range) in both SDCC and hitech and compare the t-cycles.

Quote:

Usually only very simple functions benefits register parameters. Others, like seen in the circle example, push the values into the stack anyway.

complex functions often call simple ones.

Quote:
PingPong wrote:

Or do you think that a lot of impressive achievements on those 8 bit machines like speccy msx cpc c64 were obtained by wasting cpu cycles?

Not every game or utility have to be impressive. But even with SDCC it's possible to get pretty good results, when you know how to use it.

And every last cpu cycle is not always needed. Think a game like Tetris.

think about some arcade games or others were you need to code some otherwise complex parts in c because in asm would be too complex. If I choose C+asm it's because i need a kind of efficiency.

Tetris like games and text adventure ones can even be programmed in BASIC.

By hit9918

Prophet (2868)

hit9918's picture

15-09-2019, 15:15

SDCC makes code explosion with struct acess

#include "string.h"
#include "math.h"


int main() {
        return 0;
}

struct obj {  
        int dx; int x; int dy; int y; int dz; int z;
};
typedef struct obj obj;


void test1(obj **arr) {
        obj *p = 0;
        while(1) {
                p = *arr++;
                if (!p) break;
                p->x += p->dx;
                p->y += p->dy;
        }
}
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.8.0 #10557 (MINGW64)
;--------------------------------------------------------
	.module app
	.optsdcc -mz80
	
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
	.globl _test1
	.globl _main
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _INITIALIZED
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
	.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
	.area _HOME
	.area _GSINIT
	.area _GSFINAL
	.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
	.area _HOME
	.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area _CODE
;app.c:5: int main() {
;	---------------------------------
; Function main
; ---------------------------------
_main::
;app.c:6: return 0;
	ld	hl, #0x0000
;app.c:7: }
	ret
;app.c:15: void test1(obj **arr) {
;	---------------------------------
; Function test1
; ---------------------------------
_test1::
	push	ix
	ld	ix,#0
	add	ix,sp
	push	af
;app.c:17: while(1) {
	ld	c, 4 (ix)
	ld	b, 5 (ix)
00104$:
;app.c:18: p = *arr++;
	ld	l, c
	ld	h, b
	ld	e, (hl)
	inc	hl
	ld	d, (hl)
	inc	bc
	inc	bc
;app.c:19: if (!p) break;
	ld	a, d
	or	a, e
	jr	Z,00106$
;app.c:20: p->x += p->dx;
	push	de
	pop	iy
	inc	iy
	inc	iy
	ld	a, 0 (iy)
	ld	-2 (ix), a
	ld	a, 1 (iy)
	ld	-1 (ix), a
	ld	l, e
	ld	h, d
	ld	a, (hl)
	inc	hl
	ld	h, (hl)
	add	a, -2 (ix)
	ld	l, a
	ld	a, h
	adc	a, -1 (ix)
	ld	h, a
	ld	0 (iy), l
	ld	1 (iy), h
;app.c:21: p->y += p->dy;
	ld	iy, #0x0006
	add	iy, de
	ld	a, 0 (iy)
	ld	-2 (ix), a
	ld	a, 1 (iy)
	ld	-1 (ix), a
	ex	de,hl
	ld	de, #0x0004
	add	hl, de
	ld	e, (hl)
	inc	hl
	ld	d, (hl)
	pop	hl
	push	hl
	add	hl, de
	ld	0 (iy), l
	ld	1 (iy), h
	jr	00104$
00106$:
;app.c:23: }
	ld	sp, ix
	pop	ix
	ret
	.area _CODE
	.area _INITIALIZER
	.area _CABS (ABS)

the straightforward code is this:

        ; p->x += p->dx;
        ld a,(ix+dx+0)
        add (ix+x+0)
        ld (ix+x+0),a
        ld a,(ix+dx+1)
        adc (ix+x+1)
        ld (ix+x+1),a
        ; p->y += p->dy;
        ld a,(ix+dy+0)
        add (ix+y+0)
        ld (ix+y+0),a
        ld a,(ix+dy+1)
        adc (ix+y+1)
        ld (ix+y+1),a

this lack of dealing OFFSETS is the top SDCC problem.

By PingPong

Prophet (3449)

PingPong's picture

15-09-2019, 15:23

hit9918 wrote:

SDCC makes code explosion with struct acess

#include "string.h"
#include "math.h"


int main() {
        return 0;
}

struct obj {  
        int dx; int x; int dy; int y; int dz; int z;
};
typedef struct obj obj;


void test1(obj **arr) {
        obj *p = 0;
        while(1) {
                p = *arr++;
                if (!p) break;
                p->x += p->dx;
                p->y += p->dy;
        }
}
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.8.0 #10557 (MINGW64)
;--------------------------------------------------------
	.module app
	.optsdcc -mz80
	
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
	.globl _test1
	.globl _main
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _INITIALIZED
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
	.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
	.area _HOME
	.area _GSINIT
	.area _GSFINAL
	.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
	.area _HOME
	.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area _CODE
;app.c:5: int main() {
;	---------------------------------
; Function main
; ---------------------------------
_main::
;app.c:6: return 0;
	ld	hl, #0x0000
;app.c:7: }
	ret
;app.c:15: void test1(obj **arr) {
;	---------------------------------
; Function test1
; ---------------------------------
_test1::
	push	ix
	ld	ix,#0
	add	ix,sp
	push	af
;app.c:17: while(1) {
	ld	c, 4 (ix)
	ld	b, 5 (ix)
00104$:
;app.c:18: p = *arr++;
	ld	l, c
	ld	h, b
	ld	e, (hl)
	inc	hl
	ld	d, (hl)
	inc	bc
	inc	bc
;app.c:19: if (!p) break;
	ld	a, d
	or	a, e
	jr	Z,00106$
;app.c:20: p->x += p->dx;
	push	de
	pop	iy
	inc	iy
	inc	iy
	ld	a, 0 (iy)
	ld	-2 (ix), a
	ld	a, 1 (iy)
	ld	-1 (ix), a
	ld	l, e
	ld	h, d
	ld	a, (hl)
	inc	hl
	ld	h, (hl)
	add	a, -2 (ix)
	ld	l, a
	ld	a, h
	adc	a, -1 (ix)
	ld	h, a
	ld	0 (iy), l
	ld	1 (iy), h
;app.c:21: p->y += p->dy;
	ld	iy, #0x0006
	add	iy, de
	ld	a, 0 (iy)
	ld	-2 (ix), a
	ld	a, 1 (iy)
	ld	-1 (ix), a
	ex	de,hl
	ld	de, #0x0004
	add	hl, de
	ld	e, (hl)
	inc	hl
	ld	d, (hl)
	pop	hl
	push	hl
	add	hl, de
	ld	0 (iy), l
	ld	1 (iy), h
	jr	00104$
00106$:
;app.c:23: }
	ld	sp, ix
	pop	ix
	ret
	.area _CODE
	.area _INITIALIZER
	.area _CABS (ABS)

the straightforward code is this:

        ; p->x += p->dx;
        ld a,(ix+dx+0)
        add (ix+x+0)
        ld (ix+x+0),a
        ld a,(ix+dx+1)
        adc (ix+x+1)
        ld (ix+x+1),a
        ; p->y += p->dy;
        ld a,(ix+dy+0)
        add (ix+y+0)
        ld (ix+y+0),a
        ld a,(ix+dy+1)
        adc (ix+y+1)
        ld (ix+y+1),a

this lack of dealing OFFSETS is the top SDCC problem.

Fully agree. More I ve tryed to play with opt-speed (for speed}) and opt size options but the generated code is the same. I ve also increased max-allocs-per node but no luck

By DarkSchneider

Paladin (870)

DarkSchneider's picture

15-09-2019, 15:36

hit9918 wrote:

SDCC makes code explosion with struct acess

#include "string.h"
#include "math.h"


int main() {
        return 0;
}

struct obj {  
        int dx; int x; int dy; int y; int dz; int z;
};
typedef struct obj obj;


void test1(obj **arr) {
        obj *p = 0;
        while(1) {
                p = *arr++;
                if (!p) break;
                p->x += p->dx;
                p->y += p->dy;
        }
}
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.8.0 #10557 (MINGW64)
;--------------------------------------------------------
	.module app
	.optsdcc -mz80
	
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
	.globl _test1
	.globl _main
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _INITIALIZED
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
	.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
	.area _HOME
	.area _GSINIT
	.area _GSFINAL
	.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
	.area _HOME
	.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area _CODE
;app.c:5: int main() {
;	---------------------------------
; Function main
; ---------------------------------
_main::
;app.c:6: return 0;
	ld	hl, #0x0000
;app.c:7: }
	ret
;app.c:15: void test1(obj **arr) {
;	---------------------------------
; Function test1
; ---------------------------------
_test1::
	push	ix
	ld	ix,#0
	add	ix,sp
	push	af
;app.c:17: while(1) {
	ld	c, 4 (ix)
	ld	b, 5 (ix)
00104$:
;app.c:18: p = *arr++;
	ld	l, c
	ld	h, b
	ld	e, (hl)
	inc	hl
	ld	d, (hl)
	inc	bc
	inc	bc
;app.c:19: if (!p) break;
	ld	a, d
	or	a, e
	jr	Z,00106$
;app.c:20: p->x += p->dx;
	push	de
	pop	iy
	inc	iy
	inc	iy
	ld	a, 0 (iy)
	ld	-2 (ix), a
	ld	a, 1 (iy)
	ld	-1 (ix), a
	ld	l, e
	ld	h, d
	ld	a, (hl)
	inc	hl
	ld	h, (hl)
	add	a, -2 (ix)
	ld	l, a
	ld	a, h
	adc	a, -1 (ix)
	ld	h, a
	ld	0 (iy), l
	ld	1 (iy), h
;app.c:21: p->y += p->dy;
	ld	iy, #0x0006
	add	iy, de
	ld	a, 0 (iy)
	ld	-2 (ix), a
	ld	a, 1 (iy)
	ld	-1 (ix), a
	ex	de,hl
	ld	de, #0x0004
	add	hl, de
	ld	e, (hl)
	inc	hl
	ld	d, (hl)
	pop	hl
	push	hl
	add	hl, de
	ld	0 (iy), l
	ld	1 (iy), h
	jr	00104$
00106$:
;app.c:23: }
	ld	sp, ix
	pop	ix
	ret
	.area _CODE
	.area _INITIALIZER
	.area _CABS (ABS)

the straightforward code is this:

        ; p->x += p->dx;
        ld a,(ix+dx+0)
        add (ix+x+0)
        ld (ix+x+0),a
        ld a,(ix+dx+1)
        adc (ix+x+1)
        ld (ix+x+1),a
        ; p->y += p->dy;
        ld a,(ix+dy+0)
        add (ix+y+0)
        ld (ix+y+0),a
        ld a,(ix+dy+1)
        adc (ix+y+1)
        ld (ix+y+1),a

this lack of dealing OFFSETS is the top SDCC problem.

Make obj *p static and try again.

By hit9918

Prophet (2868)

hit9918's picture

15-09-2019, 15:50

dont make the pages tall quote for just one line.

Quote:

Make obj *p static and try again.

it makes a slight improvement. it doesnt remove the base problem.

By ARTRAG

Enlighted (6251)

ARTRAG's picture

15-09-2019, 16:00

This is Hi-Tech C v780pl2



HI-TECH SOFTWARE Z80 Macro Assembler                  Sun Sep 15 15:52:56 2019

                                                                      Page   1


    1                           	global	small_model
    2                           	global	_main
    3                           	signat	_main,26
    4   0000'                   	psect	text,class=CODE
    5                           	file	"..\TEST1\TEST1.C"
    6                           	line	5
    7   0000'                   _main:
    8                           ;TEST1.C: 6: return 0;
    9                           	line	6
   10   0000' 21 0000           	ld	hl,0
   11   0003' C9                	ret	
   12                           ;TEST1.C: 7: }
   13                           	line	7
   14                           	global	_test1
   15                           	signat	_test1,4152
   16                           	line	15
   17   0004'                   _test1:
   18   0004' FD E5             	push	iy
   19                           ; _arr loaded to bc
   20                           	line	16
   21   0006' 4B                	ld	c,e
   22   0007' 42                	ld	b,d
   23                           ;TEST1.C: 16: obj *p = 0;
   24                           ; _p allocated to iy
   25   0008' FD 21 0000        	ld	iy,0
   26                           ;TEST1.C: 17: while(1) {
   27                           	line	17
   28   000C'                   l5:
   29                           ;TEST1.C: 18: p = *arr++;
   30                           	line	18
   31   000C' 69                	ld	l,c
   32   000D' 60                	ld	h,b
   33   000E' 5E                	ld	e,(hl)
   34   000F' 23                	inc	hl
   35   0010' 56                	ld	d,(hl)
   36   0011' D5                	push	de
   37   0012' FD E1             	pop	iy
   38   0014' 03                	inc	bc
   39   0015' 03                	inc	bc
   40                           ;TEST1.C: 19: if (!p) break;
   41                           	line	19
   42   0016' FD E5             	push	iy
   43   0018' E1                	pop	hl
   44   0019' 7D                	ld	a,l
   45   001A' B4                	or	h
   46   001B' 28 28             	jp	z,l3
   47                           ;TEST1.C: 20: p->x += p->dx;
   48                           	line	20
   49   001D' FD 5E 00          	ld	e,(iy+0)
   50   0020' FD 56 01          	ld	d,(iy+1)
   51   0023' FD 6E 02          	ld	l,(iy+2)
   52   0026' FD 66 03          	ld	h,(iy+3)
   53   0029' 19                	add	hl,de
   54   002A' FD 75 02          	ld	(iy+2),l
   55   002D' FD 74 03          	ld	(iy+3),h


HI-TECH SOFTWARE Z80 Macro Assembler                  Sun Sep 15 15:52:56 2019

                                                                      Page   2


   56                           ;TEST1.C: 21: p->y += p->dy;
   57                           	line	21
   58   0030' FD 5E 04          	ld	e,(iy+4)
   59   0033' FD 56 05          	ld	d,(iy+5)
   60   0036' FD 6E 06          	ld	l,(iy+6)
   61   0039' FD 66 07          	ld	h,(iy+7)
   62   003C' 19                	add	hl,de
   63   003D' FD 75 06          	ld	(iy+6),l
   64   0040' FD 74 07          	ld	(iy+7),h
   65                           ;TEST1.C: 22: }
   66                           	line	17
   67   0043' 18 C7             	jp	l5
   68                           ;TEST1.C: 23: }
   69                           	line	23
   70   0045'                   l3:
   71   0045' FD E1             	pop	iy
   72   0047' C9                	ret	


HI-TECH SOFTWARE Z80 Macro Assembler                  Sun Sep 15 15:52:56 2019

                                                                      Page   3



                      ---------- Symbol Table ----------

      (ABS) 0000#         CODE 0000          CODE 0000          CODE 0000   
      _main 0000'       _test1 0004'           l3 0045'           l5 000C'  
small_model 0000*         text 0048#  

2 jump optimizations


It has its oddness as well

By ARTRAG

Enlighted (6251)

ARTRAG's picture

15-09-2019, 16:08

Same as above in a more compact ASM format

	global	small_model
	global	_main
	signat	_main,26
	psect	text,class=CODE
	file	"TEST1.C"
	line	5
_main:
;TEST1.C: 6: return 0;
	line	6
	ld	hl,0
	ret	
;TEST1.C: 7: }
	line	7
	global	_test1
	signat	_test1,4152
	line	15
_test1:
	push	iy
; _arr loaded to bc
	line	16
	ld	c,e
	ld	b,d
;TEST1.C: 16: obj *p = 0;
; _p allocated to iy
	ld	iy,0
;TEST1.C: 17: while(1) {
	line	17
l5:
;TEST1.C: 18: p = *arr++;
	line	18
	ld	l,c
	ld	h,b
	ld	e,(hl)
	inc	hl
	ld	d,(hl)
	push	de
	pop	iy
	inc	bc
	inc	bc
;TEST1.C: 19: if (!p) break;
	line	19
	push	iy
	pop	hl
	ld	a,l
	or	h
	jp	z,l3
;TEST1.C: 20: p->x += p->dx;
	line	20
	ld	e,(iy+0)
	ld	d,(iy+1)
	ld	l,(iy+2)
	ld	h,(iy+3)
	add	hl,de
	ld	(iy+2),l
	ld	(iy+3),h
;TEST1.C: 21: p->y += p->dy;
	line	21
	ld	e,(iy+4)
	ld	d,(iy+5)
	ld	l,(iy+6)
	ld	h,(iy+7)
	add	hl,de
	ld	(iy+6),l
	ld	(iy+7),h
;TEST1.C: 22: }
	line	17
	jp	l5
;TEST1.C: 23: }
	line	23
l3:
	pop	iy
	ret	
	end
Page 14/17
7 | 8 | 9 | 10 | 11 | 12 | 13 | | 15 | 16 | 17