English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 26 June 2023, 10:31   #1
Steam Ranger
Registered User
 
Steam Ranger's Avatar
 
Join Date: May 2022
Location: Adelaide, South Australia, Australia
Posts: 208
Any reason to use assembly on the Amiga rather than C?

It seems that with modern optimising compilers and cross-compilation tools noone could write code for the Amiga better than gcc can, is there any reason to use assembly over C in 2023 for the Amiga (beyond novelty)?
Steam Ranger is offline  
Old 26 June 2023, 10:39   #2
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,346
Quote:
Originally Posted by Steam Ranger View Post
It seems that with modern optimising compilers and cross-compilation tools noone could write code for the Amiga better than gcc can, is there any reason to use assembly over C in 2023 for the Amiga (beyond novelty)?
There's plenty of reasons to use assembly for the Amiga, but probably the most valid in 2023 is because you choose to. It may come as a surprise but people actually enjoy it.

If you were developing new software, writing it in C makes sense since C has always been the main programming language for the Amiga.

As for "nobody can beat gcc", that's just not true. When sections of TKG were ported to C, GCC made lousy instruction choices for some operations that were totally obvious to assembler programmers, and we're only fixed by muddying clean C with casts to effectively guide the compiler into producing the same code the human did. And this wasn't some obscure example where you need fringe knowledge it as a bit of arithmetic with some division and modulo in it.
Karlos is offline  
Old 26 June 2023, 13:50   #3
robinsonb5
Registered User
 
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
I suspect the "nobody can beat GCC" thing is much more applicable (even if still not strictly true) true on current architectures than it is on m68k. After all, the last 20 years' worth of research and engineering effort around optimisation won't have been done with the 68000 architecture in mind.
robinsonb5 is offline  
Old 26 June 2023, 13:59   #4
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by Steam Ranger View Post
It seems that with modern optimising compilers and cross-compilation tools noone could write code for the Amiga better than gcc can, is there any reason to use assembly over C in 2023 for the Amiga (beyond novelty)?
Not really. There is sometimes the need for it if you need to access low-level features of a particular CPU (e.g. go to supervisor mode and access some of the control registers). Your average program should not do that, however.
Thomas Richter is offline  
Old 26 June 2023, 14:02   #5
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by Karlos View Post
When sections of TKG were ported to C, GCC made lousy instruction choices for some operations that were totally obvious to assembler programmers, and we're only fixed by muddying clean C with casts to effectively guide the compiler into producing the same code the human did. And this wasn't some obscure example where you need fringe knowledge it as a bit of arithmetic with some division and modulo in it.
Care about an example? (Actually, the gcc team should care more, but I'm still curious). In some cases, the choice made by the assembly programmers were just not equivalent to the C source code (or only loosely so). A typical example is a multiplication: The 68000 has "muls", but that is a 16x16->32 multiplication. That is an integer output with two short inputs. If you just multiply ints in C, that is not equilvalent in some cases, so one cannot substitute muls everyhwere where a multiplication is needed - only if you carefully tell your compiler that the input is really short, not int. As an assembler programmer, you probably know "it must be short", but if you don't tell the C compiler, it cannot possibly know.
Thomas Richter is offline  
Old 26 June 2023, 14:40   #6
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,346
Quote:
Originally Posted by Thomas Richter View Post
Care about an example? (Actually, the gcc team should care more, but I'm still curious). In some cases, the choice made by the assembly programmers were just not equivalent to the C source code (or only loosely so). A typical example is a multiplication: The 68000 has "muls", but that is a 16x16->32 multiplication. That is an integer output with two short inputs. If you just multiply ints in C, that is not equilvalent in some cases, so one cannot substitute muls everyhwere where a multiplication is needed - only if you carefully tell your compiler that the input is really short, not int. As an assembler programmer, you probably know "it must be short", but if you don't tell the C compiler, it cannot possibly know.
For the avoidance of doubt, I am not saying the compiler did this incorrectly. C has rules about the data types of intermediates in calculations and selecting the widest integer type in any expression involving mixed sizes:

https://github.com/mheyer32/alienbreed3d2/pull/88

The original assembler code for this used a 32/16 => 16r:16q operation and uses both components of the result. The code generated by the compiler would not do this until it was guided by type cast hint for the immediate.
Karlos is offline  
Old 26 June 2023, 14:58   #7
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,049
Quote:
Originally Posted by Steam Ranger View Post
...noone could write code for the Amiga better than gcc can...
Every single c/'c++ compiler produces bad m68k code. If you know how the code should look like in asm, you can give it hints by writing the code in a specific way to produce acceptable code (e.g. demos by the Abyss guys written in c are a good example), but in general it's still bad code. Yeah, in some cases you don't care about all that and your acceptance criteria are something like: 1. it works, 2. less time coding and more time XYZ, 3. it's kind of portable, so you just go with it.

Anyway:
1. because you can (zero effs given)
2. because you want to challenge yourself
3. because you're tired of dealing with c/c++ as part of your job
a/b is offline  
Old 26 June 2023, 15:21   #8
arcanist
Registered User
 
Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 410
Quote:
Originally Posted by robinsonb5 View Post
I suspect the "nobody can beat GCC" thing is much more applicable (even if still not strictly true) true on current architectures than it is on m68k. After all, the last 20 years' worth of research and engineering effort around optimisation won't have been done with the 68000 architecture in mind.
I'd say it's worse on modern CPUs, not better.

Compiler developers have been trying to improve autovectorization since the dawn of SSE and GCC still does a terrible job of it. Where ALU throughput matters and the algorithm can be vectorized we still lean heavily on intrinsics; the half-way house between C and assembly.

For 68K I was unable to coerce GCC into generating code as efficient as this, which gave a great speed-up.
arcanist is offline  
Old 26 June 2023, 15:58   #9
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by Karlos View Post
The original assembler code for this used a 32/16 => 16r:16q operation and uses both components of the result. The code generated by the compiler would not do this until it was guided by type cast hint for the immediate.
That's a classic, and here the compiler misses indeed an optimization, namely understanding that 1000 fits into a UWORD and does not need to be handled as integer. Again, write to to gcc folks and get it fixed.
Thomas Richter is offline  
Old 26 June 2023, 16:00   #10
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by a/b View Post
Every single c/'c++ compiler produces bad m68k code.
That is, in this generality, outright wrong. A C compiler can optimize for multiple targets, and can create code you find "unexpected" or "unpleasant", but it may also generate code you would probably not write in such a way yourself, though the speed or the size of the code is then nevertheless convincing.
The output of gcc on x64 at least nowadays sometimes really surprises me in the way what the compiler can actually do.
Thomas Richter is offline  
Old 26 June 2023, 16:05   #11
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by arcanist View Post
I'd say it's worse on modern CPUs, not better.
It is actually better. The trouble is that x64 with all its extensions became such an unorthogonal beast.


Quote:
Originally Posted by arcanist View Post
Compiler developers have been trying to improve autovectorization since the dawn of SSE and GCC still does a terrible job of it. Where ALU throughput matters and the algorithm can be vectorized we still lean heavily on intrinsics; the half-way house between C and assembly.
And yet you (and me, in our office) write that with intrinsics in C++, and not in assembler, which is pretty much a point for the flexibility of C, and against the hard-to-handle assembler.


Quote:
Originally Posted by arcanist View Post

For 68K I was unable to coerce GCC into generating code as efficient as this, which gave a great speed-up.
And yet, this pretty much proves the point, namely almost all of it is *not* assembler. Why would it, if only the execution speed of a small bottleneck matters.


In fact, this is how we work these days. Find bottlenecks, isolate them into separate classes, rewrite those classes with intrinsics. Nobody bothers writing in assembler anymore.
Thomas Richter is offline  
Old 26 June 2023, 16:15   #12
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,346
I think we are all losing sight of what I propose is the most important reason anyone might use assembler for programming on the Amiga: they just want/prefer to. It's not as if the platform is in any kind of competition commercially and the entire userbase is made up of enthusiasts. Everything anyone does with it is basically for fun.

I mostly use C++ and C for Amiga but I'll happily use assembler where I feel I can improve something beyond what the compiler can manage or if I want some especially hands on control of something.
Karlos is offline  
Old 26 June 2023, 16:30   #13
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,350
Quote:
Originally Posted by Steam Ranger View Post
It seems that with modern optimising compilers and cross-compilation tools noone could write code for the Amiga better than gcc can,
Definitely not for 68k. I can beat gcc anytime, and usually by a factor 2-4 (depending on what the code codes). Losing 50-75% of cpu time (sometimes more, especially for C++) is something that requires a good justification.
And on other cpus i suspect the compilers win mainly because nobody really challenges them.


Quote:
Originally Posted by Steam Ranger View Post
is there any reason to use assembly over C in 2023 for the Amiga (beyond novelty)?
There are many.
Asm is the best coding school. Once you master it, you are a better coder overall because you know how things work.
It provides more coding freedom. You do whatever you want.
Obviously your code will be shorter and faster.
In asm you can call any function located anywhere in the source, without prior declaration. Last time i've looked, in C you had to either pay attention to order, or define same thing several times.
C syntax is simply horrible
In asm you can have nice, aligned, one-comment per code line.
Unlike C, in asm you will not run into undefined behaviours without even knowing it because the spec is so overcomplicated and nobody knows it fully.
Do you want more ?
(now i have the feeling this will end up in a flame war...)



Quote:
Originally Posted by Thomas Richter View Post
Again, write to to gcc folks and get it fixed.
I am afraid they pay little attention to m68k these days.


Quote:
Originally Posted by Thomas Richter View Post
That is, in this generality, outright wrong. A C compiler can optimize for multiple targets, and can create code you find "unexpected" or "unpleasant", but it may also generate code you would probably not write in such a way yourself, though the speed or the size of the code is then nevertheless convincing.
The output of gcc on x64 at least nowadays sometimes really surprises me in the way what the compiler can actually do.
The thread title mentions "Amiga", not "x64".


Quote:
Originally Posted by Thomas Richter View Post
And yet you (and me, in our office) write that with intrinsics in C++, and not in assembler, which is pretty much a point for the flexibility of C, and against the hard-to-handle assembler.
Not applicable to Amiga.


Quote:
Originally Posted by Thomas Richter View Post
In fact, this is how we work these days. Find bottlenecks, isolate them into separate classes, rewrite those classes with intrinsics. Nobody bothers writing in assembler anymore.
While overall true, again this does not apply for Amiga - where quite few people hopefully still write asm.
meynaf is offline  
Old 26 June 2023, 16:43   #14
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by meynaf View Post
Definitely not for 68k. I can beat gcc anytime, and usually by a factor 2-4 (depending on what the code codes).
At the expense of one order of magnitude increase in development time. (-:


Quote:
Originally Posted by meynaf View Post
There are many.
Asm is the best coding school. Once you master it, you are a better coder overall because you know how things work.
And if you don't do, you may be a better software engineer (as opposed to "coder"), because you learn how to structure your code and how to design a software architecture. That is something assembler does not teach you.


Quote:
Originally Posted by meynaf View Post
It provides more coding freedom. You do whatever you want.
The problem is "if you do what you want", you probably do not mind that you may "want something different in the future", and for that target, structure and notation helps, and asssembler is very bad providing it.


Consider you need to change your algorithm later on because the use case of your program changed, or the data changed. Try to remember what you did 3 years ago in an assembler program. That can be very painful.


Actually, that is pretty much the difference between "coding" and "engineering".


Quote:
Originally Posted by meynaf View Post
Obviously your code will be shorter and faster.
And almost surely non-working, only after some painful debugging sessins, and not maintainable.


Quote:
Originally Posted by meynaf View Post
In asm you can call any function located anywhere in the source, without prior declaration.
Guess what, in C you can also call functions anywhere in the code, and the declarations help you and the compiler to remember how to call them and which arguments they take. Even better, the compiler can check that for you, and will remind you if you do not provide them correctly.


Quote:
Originally Posted by meynaf View Post
In asm you can have nice, aligned, one-comment per code line.
Unlike C, in asm you will not run into undefined behaviours without even knowing it because the spec is so overcomplicated and nobody knows it fully.
If you run into UB, you probalby do not know well enough. Don't confuse "nobody" with "you". Probably you do not know, but that does not exclude others.


Quote:
Originally Posted by meynaf View Post

Not applicable to Amiga.
But sure it is. Entire AmigaOs is a mixture of C and assembler, and only bottlenecks are in assembler. P96 works likewise. The heavy-duty algorithms are in assembler because it matters that the algorithms are fast. The higher level logic is in C because there it matters that you express the structure clearly to keep the code maintainable.
Thomas Richter is offline  
Old 26 June 2023, 17:08   #15
grond
Registered User
 
Join Date: Jun 2015
Location: Germany
Posts: 1,923
I would also say that it is mostly about subjective reasons such as fun and personal preferences. If you address the bare 68000 configuration and have some ambitious goals, you certainly need every CPU-cycle and wouldn't want them wasted my a compiler producing suboptimal code (and even if it is only because the compiler can't possibly consider all constraints and side conditions that you can in assembly language).

To me assembly coding gives me a feeling of control which is due to the fact that I simply don't understand much about higher-level programming languages which abstract things away and do unexpected things under the hood I don't know about. I guess that feeling goes away with experience in programming in high-level languages but I never did that enough. I'm a microelectronics guy and understand about transistors and digital logic which makes assembly language close enough to my field of expertise.
grond is offline  
Old 26 June 2023, 17:13   #16
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,350
Quote:
Originally Posted by Thomas Richter View Post
At the expense of one order of magnitude increase in development time. (-:
As a program is executed many more times than it is written, this is quite acceptable.


Quote:
Originally Posted by Thomas Richter View Post
And if you don't do, you may be a better software engineer (as opposed to "coder"), because you learn how to structure your code and how to design a software architecture. That is something assembler does not teach you.
This is something no language at all will teach you.


Quote:
Originally Posted by Thomas Richter View Post
The problem is "if you do what you want", you probably do not mind that you may "want something different in the future", and for that target, structure and notation helps, and asssembler is very bad providing it.
I can want something different in the future, where is the problem ?
Assembler does not need to provide anything special, nor do other languages.


Quote:
Originally Posted by Thomas Richter View Post
Consider you need to change your algorithm later on because the use case of your program changed, or the data changed. Try to remember what you did 3 years ago in an assembler program. That can be very painful.
This is painful only if you did it wrong. If you did it right, you've put enough comments in the code and you don't need to remember what you did 3 years ago - it's just written in a more clear way than any coding language can tell.


Quote:
Originally Posted by Thomas Richter View Post
Actually, that is pretty much the difference between "coding" and "engineering".
Right. "Engineering" does not provide code that works.


Quote:
Originally Posted by Thomas Richter View Post
And almost surely non-working, only after some painful debugging sessins, and not maintainable.
Yes of course it will work, and debugging in asm isn't as painful as with C.
That, because we're in "fail early and fail big" environment, as opposed to "fail silently and keep going".


Quote:
Originally Posted by Thomas Richter View Post
Guess what, in C you can also call functions anywhere in the code,
NOT without a prior declaration ! That was the point.


Quote:
Originally Posted by Thomas Richter View Post
and the declarations help you and the compiler to remember how to call them and which arguments they take. Even better, the compiler can check that for you, and will remind you if you do not provide them correctly.
No, the compiler can not check that. It only checks the basic types of the arguments, not the meaning of them. Three ints are three ints, even when swapped.
If in asm you swap argument types, be sure the code won't work at all and you'll quickly find out why. In C, especially C++, it may eventually make some silent, damaging conversions without telling you.
Only right way to code is to not attempt to have the computer do it at your place, but verify yourself everything you do.


Quote:
Originally Posted by Thomas Richter View Post
If you run into UB, you probalby do not know well enough. Don't confuse "nobody" with "you". Probably you do not know, but that does not exclude others.
If there is more to know than i do, then there is too much to know.
Why would i care with something overcomplicated, just because a few others can ? And are you sure you really know the full C spec, with all its details ? Perhaps you should read it again.


Quote:
Originally Posted by Thomas Richter View Post
But sure it is. Entire AmigaOs is a mixture of C and assembler, and only bottlenecks are in assembler. P96 works likewise. The heavy-duty algorithms are in assembler because it matters that the algorithms are fast. The higher level logic is in C because there it matters that you express the structure clearly to keep the code maintainable.
There are no intrinsics in AmigaOS or P96, especially not vectorized stuff. Read again what my "not applicable to Amiga" was replying to (at several levels).
meynaf is offline  
Old 26 June 2023, 17:39   #17
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,049
Quote:
Originally Posted by Thomas Richter View Post
That is, in this generality, outright wrong.
Not in the slightest. Handwritten m68k code by a good asm programmer > gcc code. Yes, there will occasionally be a small case, some weird trick, where gcc wins, but, in general, there is no way in hell gcc (or any c/c++ compiler) can produce faster and smaller code than handwritten m68k.

That's all I'm saying, based on my personal experience (writting m68k asm since 90's, last ~5 years pretty much all my spare time doing that). To give you an example... 68000-060 disassembler, supports old and new syntax, selectable target cpu/mmu/fpu, optional opcode hexdump, all code+data+strings+tables = 7184 bytes. Good luck doing that in c/c++.

I'm not arguing about development time, efficiency, portability, .... I wouldn't even suggest anyone to use asm instead of c/c++.
a/b is offline  
Old 26 June 2023, 20:22   #18
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,971
Quote:
Originally Posted by meynaf View Post
[...] While overall true, again this does not apply for Amiga - where quite few people hopefully still write asm.
Or learn it on their spare time .

Quote:
Originally Posted by Thomas Richter View Post
[...] Consider you need to change your algorithm later on because the use case of your program changed, or the data changed. Try to remember what you did 3 years ago in an assembler program. That can be very painful. [...]
I don't see how using C (or any other language) over asm will better help you remember what you have coded ?!?
After 3 years, even a batch script can be very painful to understand without comments .
And commenting code is "just" a good practice whatever language you code in.
In this regard, using C is of no help at all.
malko is offline  
Old 26 June 2023, 21:12   #19
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,346
Some of us are so lame, we write stuff C++ and even scripting languages to allow us to pretend we still write 68K ... https://github.com/0xABADCAFE/MC64000
Karlos is offline  
Old 26 June 2023, 22:28   #20
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,288
Quote:
Originally Posted by meynaf View Post
As a program is executed many more times than it is written, this is quite acceptable.
That's simply not the case with living software. You seem to (falsely) assume that a program is at a point "finished", and then you do not touch it anymore. That is rarely the case in practical applications. Customers come, have feature requests, want changes, report issues. Even on the Amiga.


Now, try to maintain an assembly program.


Quote:
Originally Posted by meynaf View Post
This is painful only if you did it wrong. If you did it right, you've put enough comments in the code and you don't need to remember what you did 3 years ago - it's just written in a more clear way than any coding language can tell.
No, that's neither true. The difference is that a high level syntax helps you to formulate design decisions (or encode them) such that the compiler can help you to verify that the interfaces in your code are used correctly. That is incredibly helpful on large programs.




Quote:
Originally Posted by meynaf View Post

Yes of course it will work, and debugging in asm isn't as painful as with C.
Nope. The first step of "debugging" higher level language code is to have the compiler check it for you. If it compiles, you already have a part of the deal. In assembler, nobody tells you whether whether you put the right arguments into the right registers.


Quote:
Originally Posted by meynaf View Post


NOT without a prior declaration ! That was the point.
The point in "declarations" is to help you, not to struggle you. It provides a first level barrier for code checking.


Quote:
Originally Posted by meynaf View Post
No, the compiler can not check that. It only checks the basic types of the arguments, not the meaning of them. Three ints are three ints, even when swapped.
Then don't make them ints. There are reasons for data structures to express your intent. In assembler, a pointer is a pointer. In C, that is not the case. For reasons.




Quote:
Originally Posted by meynaf View Post
If in asm you swap argument types, be sure the code won't work at all and you'll quickly find out why. In C, especially C++, it may eventually make some silent, damaging conversions without telling you.
I don't know which kind of C or C++ you write...


Quote:
Originally Posted by meynaf View Post
Only right way to code is to not attempt to have the computer do it at your place, but verify yourself everything you do.
That is the stupid way.


Quote:
Originally Posted by meynaf View Post
If there is more to know than i do, then there is too much to know.
Why would i care with something overcomplicated, just because a few others can ? And are you sure you really know the full C spec, with all its details ? Perhaps you should read it again.
Why do you bother? I know what I know, and I do not run into problems with UB. Actually, my compiler warns me if the code depends on UB. Assembler does not. If I put a pointer of one data structure into a function argument for another data structure, nothing stops the assembler.



War time story, from another thread just in this forum: Do you know why the CON: handler only hides its window instead of closing it when pressing the iconification button? Because nobody understands how the console.device operates. It is opaque assembly code. If that would have been C code with proper data structures, it would be relatively straight foreward to update the code such that the console character map can exist without its window, but the way how the code operates (in assembler) is just opaque, and it is somewhat documented. In the assembler programming style.


In other words: You have not yet had in contact to reality if you make such nonsense claims. Assembler code is to a good degree write-only code, probably understandable for its author. The expressiveness of the language (if you call it so) is not sufficient to document intentions of the author and encode it in the syntax. C is not perfect, but better. C++ is even better to formulate designs, but it already has "too many" features that can be easily misused to make thinks less readable rather than more readable.
Thomas Richter is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Chat GPT Amiga Assembly rcman Coders. Asm / Hardware 3 26 March 2023 20:24
An Amiga coder was banned without a reason - is it ok? litwr project.EAB 1 18 June 2021 20:38
Beginning Amiga Assembly Tutorial(s) Curbie Coders. Asm / Hardware 15 29 May 2020 00:21
Beginning Amiga Assembly Programming Hewitson Coders. Tutorials 32 09 October 2012 18:25
Amiga Assembly sources - Please help! W4r3DeV1L Amiga scene 21 16 July 2008 08:13

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 11:59.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13441 seconds with 14 queries