D Finnigan wrote:
Michael J. Mahon wrote:D Finnigan wrote:Michael Black wrote:On Mon, 22 Feb 2010, D Finnigan wrote:Thanks to everyone's responses, I've decided to slow down, man up, and learn to program in C for the Apple IIe, and also hopefully learn more assembly as well.Assembly is pretty fast, C is really slow.Slower even than Applesoft? That's not the impression that I got.Assembly language is easily a few hundred times faster than Applesoft, and usually 2x-3x faster than compiled code, since the assembly language programmer allocates machine registers "perfectly" for speed and uses "ideal" machine-oriented data structures, not a few "standard" types provided by a programming language. (Of course, if all the time is spent in libraries, those libraries will determine the speed.) Any production OS intended to run on a (small fraction of a) 64KB machine can and should be written in assembly language, for compactness as much as speed and versatility. 16KB of 6502 code is less than 5-6k lines of code, and therefore well within the range of easily managed assembly programs--assuming reasonable factoring, macros, etc.I noticed that Aztec C has its own assembler and the C compiler has an option to convert the C source to assembly without actually doing the assembling. Would it be worthwhile to hand-tune the generated assembly file?
Certainly some significant gains can be obtained by hand-optimizing the compiler's output in important areas--even as far as substituting pure assembler code for time-consuming inner loops. But what cannot typically be done is any improvement in the fundamental register usage. For example, it is easy to implement assembly language programs that use all the registers to communicate parameters and return values with minimal "wasted motion", but a compiler will usually need to assume that one or more registers are always "scratch", precluding their use for communication. Another example is array handling. Where a compiled language allocates an array of 16-bit integers as contiguous elements, an assembly language programmer often allocates two "parallel" 8-bit arrays. The result is that the compiler needs to do full 16-bit address arithmetic to create a 16-bit pointer to the selected array element, while the assembler programmer simply puts the index into an index register and indexes separately to the low and high parts of the selected 16-bit element. This is a huge efficiency difference, in both speed and code space. This approach is not fully general--it only applies to arrays with no more than 256 elements, but that constitutes the vast majority of arrays. In general, compilers use "portable" data models, while assembly programmers often use very machine-specific data models--to the great advantage of assembly language programs. The "general" assumptions of a compiler rule out its use of many major simplifying code generation strategies, and even constrain the context for modifying compiler-generated code by hand. -michael NadaNet and AppleCrate II: parallel computing for Apple II computers! Home page: http://home.comcast.net/~mjmahon "The wastebasket is our most important design tool--and it's seriously underused."