About C / Z80 optimizations (SDCC)

Page 8/15
1 | 2 | 3 | 4 | 5 | 6 | 7 | | 9 | 10 | 11 | 12 | 13

By PingPong

Prophet (3413)

PingPong's picture

10-09-2019, 19:26

DarkSchneider wrote:

It is usually better. But SDCC is currently very close. As mentioned, on later releases they sometimes include the optimizations of the z88dk branch into the main.
In any case a few cycles is nothing to worry about. I see the current SDCC nice.

Optimizations?

By PingPong

Prophet (3413)

PingPong's picture

10-09-2019, 19:53

Z80 stack is 16 bit based.
SDCC try to use as 8 bit stack
So the very inefficient Inc sp FOR EACH 8 bit var pushed on the stack
Practically it loose any benefit of using the relatively fast push pop on z80
Very bad code

By zPasi

Champion (410)

zPasi's picture

10-09-2019, 20:44

PingPong wrote:

Z80 stack is 16 bit based.
SDCC try to use as 8 bit stack
So the very inefficient Inc sp FOR EACH 8 bit var pushed on the stack

No it doesn't. Perhaps you didn't read my post properly.

And "very inefficient Inc sp"? Six cycles. C'mon!

By DarkSchneider

Paladin (854)

DarkSchneider's picture

10-09-2019, 21:55

@PingPong I think you are based on a very old SDCC version. As we can see a few messages above it uses it like a 16-bit stack.
What it does it optimize the use of the stack. If you use 8-bit values and have to move to the stack it uses the full space.

By PingPong

Prophet (3413)

PingPong's picture

10-09-2019, 21:57

zPasi wrote:
PingPong wrote:

Z80 stack is 16 bit based.
SDCC try to use as 8 bit stack
So the very inefficient Inc sp FOR EACH 8 bit var pushed on the stack

No it doesn't. Perhaps you didn't read my post properly.

And "very inefficient Inc sp"? Six cycles. C'mon!

It IS: or do you know some assembly instruction like PUSH A or PUSH C ? all stack instructions work on 16 bit quantities.
Plus the overhead on 6 cycles is extremely heavy. PUSH OR pop TAKES 10 OR 11 T-STATES. Adding an overhead of 6 cycles means a slowdown of more than 50%. Let's call some hundred of calls and you wasted a lot of cycles.

By the way no one say that things should work in a 8 bit quantity. With only the exception of recursive calls ( that are not so much used on z80 ) wasting another byte and avoiding 8 bit stack would have been more efficient. At least with a compiler option.

the stack setup /cleanup code generated by SDCC to perform a simple call is something of inefficient. looking to the example above, 140 cycles is a LOT to perform a single call.

By PingPong

Prophet (3413)

PingPong's picture

10-09-2019, 22:20

DarkSchneider wrote:

What it does it optimize the use of the stack. If you use 8-bit values and have to move to the stack it uses the full space.

My assumptions are based on example above
plus what does it mean the quoted sentence? i cannot understand what your are telling me. can you explain a bit?
if you are meaning that it uses the stack to conserve space on it, i can say you that it does this paying excessive cost of execution time!
z80 can use 64KB of stack so is less limited with respect to other processors like 6502 for example.

using 16 bit quantities is not so dramatically relevant. remember that stack is pushed and popped and except a very big deep level of calls (as in recursion, rarely used ) using 16 bits for 8 bits values is not so huge space waste. Instead the time wasted is more thatn 50% for every 8 bit value you use.

I think SDCC does this because internally is designed to work with processors with 8 bit stack, so on processors that can push only 8 bit on the stack there is no problem. However with z80 that works only with 16 bit quantities would have been better to use the 16 bit mode.

So, it is not a space optimization but most probably an internal design limit of the compiler. I also think that is not so easy to fix.

By DarkSchneider

Paladin (854)

DarkSchneider's picture

10-09-2019, 22:43

You spend a INC SP to push the value, but you save a POP to get it at the function, as you get 2 8-bit values into registers with only one POP.
Also a 50% only when you push 8-bit values, is all your code doing that? And a 50% that can be a 100% of benefit inside the called function.
And, in addition, you have all the values in sequence without garbage in the middle, so it could even place HL at start of the sequence and read using HL in a row if required.
So not knowing how the values are read and used inside the functions is not good to speculate about it.

The thread is about using well the compiler, well, if you want to push the values as 16-bit, then simply Cast them to 16-bit at function calling and voilà. You have the best of both worlds.

By PingPong

Prophet (3413)

PingPong's picture

10-09-2019, 23:13

DarkSchneider wrote:

You spend a INC SP to push the value, but you save a POP to get it at the function, as you get 2 8-bit values into registers with only one POP.

no, to get the value inside the function the code use ix or ix based address, so it is irrelevant to read at any offset, if you are meaning that.

Quote:

Also a 50% only when you push 8-bit values, is all your code doing that? And a 50% that can be a 100% of benefit inside the called function.

sorry unclear meaning, what are you meaning?
as said there is no benefit inside the function when accessing parameters. if you read parameters vi ix or iy registers. Instead, if you do some stack manipulation i can say you that the same thing could be performed by SDCC when pushing the parameters. But i think it is too much complex to handle

Quote:

So not knowing how the values are read and used inside the functions is not good to speculate about it.

False. we know how sdcc push or pop values because we read the documentation.
Plus, the way a compiler setup the stack frame is implementation specific. there is no one telling you the rule to use.
the only thing to know ( if we do asm interfacing ) is how the compiler setup parameter passing and return values.

Quote:

The thread is about using well the compiler, well, if you want to push the values as 16-bit, then simply Cast them to 16-bit at function calling and voilà. You have the best of both worlds.

That's a very weird usage and implies to use a trick to force the compiler to do smart /right things.
If i'm forced to use a 16 bit value instead of 8 bit one only to compensate the pushed value it is crappy:
- because i generate confusion in others reading my source code "why this used this 16 bit parameter for a 8 bit value" ?
- if i want to change compiler it may prevent some kind of optimizations available with the right data type.

What you are suggesting me is similar to use all float values because they can represent a wide range of values vs byte ones.

It is not best of world, it is a limiting factor

SO understand i may hurt you by pointing all the deficiencies of this compiler, but facts are facts.

By zPasi

Champion (410)

zPasi's picture

11-09-2019, 08:58

PingPong wrote:

It IS: or do you know some assembly instruction like PUSH A or PUSH C ? all stack instructions work on 16 bit quantities.

SDCC is able of pushing two 8-bit parameters by one push instruction. What puzzles me is that SDCC does that optimization in one place and ZSDCC in another. I think eventually the devs will get the optimizations in place in both cases.

But it's not such a big deal anyway. Typically you just don't use functions with many parameters in tight time-critical loops. You can use globals, structs, even inline functions.

And, also Hi-Tech C uses stack for parameters and locals, so I doubt the difference is significant.

By DarkSchneider

Paladin (854)

DarkSchneider's picture

11-09-2019, 09:39

You always have to know your tool. In compiler it does not exist that "the same for everything". Each one has its own policies. You can also face problems with promoting to int when operating, I have my code for another compiler full of casting to "unsigned char" to avoid that.
Even on modern compilers for modern machines we have that, i.e. in structure alignment. The compiler can align structures to CPU word size, adding bytes at the end, so if you compile with that option, upload the generated OBJ, and the other part compiles without that option, it will silently crash with no apparent reason.
Or depending we have many sizes for the same "int" type, it can be 16 or 32 bits. So the exact same code is not valid.
So, in any case, you have to advice about how do you do things, as there are no universal rules concerning compilers. It can be advicing about compiler options, or in the code, I had seen myself adding BYTE align[xx] at the end of structures because I though it was more clear and worked in all compilers.
One could simply make pure C code, not considering any align or anything, and advice about compiling disabling everything in the compiler to be sure it works, but then we could have align problems, losing some of those cycles. You could notice less because modern machines are fast, but it is there.
Adapting and advicing in the code is simply another way to do the same, if someone codes with SDCC as base, can simply promote the parameters to 16-bit, and then inside the function do not touch the parameter but for assigning it to a 8 bit variable, that would do the trick. And, on function specification comments, for that parameter put "8-bit value promoted to 16-bit for alignment".
Copied from another site:

Quote:

Right, passing chars as parameter. I'd forgotten about that because I changed all my functions to accept int instead of char to avoid problems.
Once you change a parameter to int (from char), the code generated is different for the function. sdcc is much better with generating code for char types so by changing things to int you do lose something in the code generation. You could assign the int param to a local char before using it to get around that.

It is not so hard.

At the end, in any case, for compilers you have to know the tool you are using and its policies, to use it adequately. There is no exception to this, even on modern compilers on modern machines, as mentioned, at least with how C compilers work.

PingPong wrote:

SO understand i may hurt you by pointing all the deficiencies of this compiler, but facts are facts.

Yes, the fact that how high is the lack of education nowadays. Hurt me, because how SDCC uses stack, seriously? Sure, that's what gives meaning to my life. Tried to hold a conversation but I stop here, no need to face extreme stubbornness, as it is not my duty to fill the lifetime of anyone.

Page 8/15
1 | 2 | 3 | 4 | 5 | 6 | 7 | | 9 | 10 | 11 | 12 | 13