• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

Performance limitations for 68000 Macs

Snial

68000
Hi folks,

Sometimes I'm reminded of the underlying limitations of old, compact, 68K Macs. I tried a little experiment with MacPascal 1.0 on an InfiniteMac emulation of a Mac 512Ke.

1725268288017.png
It's a simple program that just keeps allocating 1kB; reporting how many times it's done that and the elapsed time. I've attached the MacPascal disk image so you can play with it. The version on the .disk is a bit neater as it allows for 5 digits for the time (as a longint) and converts it to 0.1s units.

There's a couple of upshots from this program. Firstly, it doesn't exit properly, it just hangs at 359kB to 361kB. This means (512-361-22-(361*16/1024)) 123kB is being used by the system + MacPascal, under System 2.0. Perhaps Mac Pascal isn't allowing for a rainy-day memory fund.

The next thing to notice is how slow it gets. By 95kB, it's already taking 0.68s per allocation, but by the last allocation it's taken 2737.4s in total, on average that's about 7.6s per allocation! It gets really slow by then.

Some of this is probably because every block will be cleared, but that's relatively small compared with the allocation time. MacPascal's interpretive implementation won't actually contribute that much, because it's still going to operate at 1000s of lines per second. This leave heap allocation itself, though I'm surprised that even a linear scan through 361 memory blocks to find space would take so long. Perhaps MacPascal uses its own slow heap management - I'll have to compare it with NewPtr.

But the upshot is that you can't just fix 8MHz compact Mac issues with more RAM. Archaic heap allocation algorithms and sheer speed limitations of these old machines can limit what can be achieved using dynamic memory allocation.
 

Attachments

There's a couple of upshots from this program. Firstly, it doesn't exit properly, it just hangs at 359kB to 361kB. This means (512-361-22-(361*16/1024)) 123kB is being used by the system + MacPascal, under System 2.0. Perhaps Mac Pascal isn't allowing for a rainy-day memory fund.

What happens if you call the OS NewPtr instead of MacPascal's 'new'? Or NewHandle?
 
What happens if you call the OS NewPtr instead of MacPascal's 'new'? Or NewHandle?
That was going to be my next test. I've tried to define:
Code:
...
const
    NewPtr=$A11E;
var
    gBlock:longint;
begin
    repeat
        {... much as before...}
        gBlock=LInlineF(NewPtr,1024);
    until gBlock=0;
end.
Unfortunately it crashes at the LInlineF. I think this is because $A11E isn't a standard toolbox call with a Pascal interface.

I don't seem to be able to properly download and view Inside Macintosh 1 and I'm not at home to read my actual paper copy. So, I'm not sure of the exact interface for NewPtr right now. From http://www.mac.linux-m68k.org/devel/macalmanac.php

"
Trap word bits are defined as follows.

Bits 15 through 12 are set to the binary pattern 1010 (hexdecimal A) for all
traps.

Bit 11 determines the trap's category: 1 for Toolbox traps and 0 for Operating
System traps.

For OS traps, bits 10 and 9 are used for flags, whose meanings depend on the
routine being called. For Toolbox traps, bit 10 is the auto-pop bit. If it is
set, the Trap Dispatcher will remove, or "pop", the return address from the top
of the stack and throw it out. It will then pop the stack again and use that
address as the return address. This feature supports languages such as Lisa
Pascal that always JSR'd to a table of trap words (instead of inserting the
trap words inline with the code).

Bit 9 is a reserved bit in Toolbox trap words in the 64K and 128K ROMs. Apple
added the bit to the trap number on all later ROMs.

Bit 8 is used by OS traps to preserve the 68000's register A0 across a system
call. If the bit is 0, register A0 is saved before the system call begins
execution and restored after it finishes. If the bit is 1, register A0 is not
saved and restored (allows OS routines that resturn a value in A0 to work).

Bits 7 through 0 comprise all or part of the trap number for all traps.

"
 
It's an OS trap, so parameters are passed in registers. I thought MacPascal had an OS interface; if not, then this will be rather more annoying...
 
It's an OS trap, so parameters are passed in registers. I thought MacPascal had an OS interface; if not, then this will be rather more annoying...
It has a MacTraps interface for ToolBox APIs that use the pascal calling convention, unless it somehow interprets the trap numbers themselves. My next attempt was to use ThinkC under System 7 to write an app in 'C' which can do the same job. It still crashes when I run it on System 3, I think I need to add InitPacks().

Actually, I solved the problem for why the ThinkC version was crashing under System 3 or System 2. It was because my gWNEImplemented routine which uses NGetTrapAddress() doesn't work under those Systems. I should go back and refer to the technique used in https://68kmla.org/bb/index.php?thr...-os-system-1-using-codewarrior-gold-11.47511/

I just do:

1725313810160.png
I've now undefined optTrapCheck.

So, when I run the application - I forgot to change the window name from my MiniMorse name. This is the final screenshot when run on a Mac 512Ke under System 2 on InfiniteMac:

1725313619787.png
So, basically what happened was that, the app is much smaller for a start (<3kB): so Allocs go up to 424. Secondly, it updates really quickly; all but the last few of them don't seem to slow down when being allocated. Thirdly, through most of the application, it's all displayed in Monaco 9 as intended, but at the end it suddenly slows down and switches to this awful font, which I suspect is a scaled Chicago 9pt. The "Mem:" bit is just my rubbish technique for preventing the NewPtr from being optimised out.

So, this is the new conclusion: MacPascal has a terrible memory allocator! When it's all done properly in assembler or a compiled language it's super-fast. Which is good!
 
Last edited:
Back
Top