Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.apple2.programmer > #4358 > unrolled thread

PLASMA 2.0

Started byDavid Schmenk <dschmenk@gmail.com>
First post2018-03-16 11:43 -0700
Last post2018-04-25 06:37 -0700
Articles 19 on this page of 59 — 14 participants

Back to article view | Back to comp.sys.apple2.programmer


Contents

  PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-16 11:43 -0700
    Re: PLASMA 2.0 Steve Nickolas <usotsuki@buric.co> - 2018-03-16 20:47 -0400
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-17 07:06 -0700
    Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-03-16 18:00 -0700
      Re: PLASMA 2.0 Antoine Vignau <antoine.vignau@laposte.net> - 2018-03-16 22:18 -0700
        Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-17 07:36 -0700
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-17 07:34 -0700
        Re: PLASMA 2.0 Michael J. Mahon <mjmahon@aol.com> - 2018-03-17 10:05 -0500
          Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-17 20:56 -0700
            Re: PLASMA 2.0 Michael J. Mahon <mjmahon@aol.com> - 2018-03-18 00:59 -0500
              Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-18 07:47 -0700
                Re: PLASMA 2.0 Michael J. Mahon <mjmahon@aol.com> - 2018-03-21 00:23 -0500
        Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-03-18 01:10 -0700
          Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-18 08:06 -0700
            Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-03-18 12:20 -0700
              Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-18 13:56 -0700
                Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-03-18 17:35 -0700
    Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-23 13:32 -0700
      Re: PLASMA 2.0 Antoine Vignau <antoine.vignau@laposte.net> - 2018-03-23 14:07 -0700
        Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-23 17:22 -0700
    Re: PLASMA 2.0 Michael Mann <gmail@ware4.com> - 2018-03-23 16:44 -0700
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-23 17:20 -0700
        Re: PLASMA 2.0 mmphosis <mmphosis@macgui.com> - 2018-03-24 01:13 +0000
          Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-23 19:09 -0700
        Re: PLASMA 2.0 Steve Nickolas <usotsuki@buric.co> - 2018-03-23 21:55 -0400
          Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-23 19:12 -0700
            Re: PLASMA 2.0 Antoine Vignau <antoine.vignau@laposte.net> - 2018-03-24 00:34 -0700
              Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-24 07:51 -0700
    Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-28 15:39 -0700
      Re: PLASMA 2.0 Michael J. Mahon <mjmahon@aol.com> - 2018-03-28 20:52 -0500
        Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-29 07:17 -0700
          Re: PLASMA 2.0 Zellyn <zellyn@gmail.com> - 2018-03-29 08:12 -0700
            Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-29 22:19 -0700
    Re: PLASMA 2.0 Tom Porter <laseractiveguy@gmail.com> - 2018-03-28 23:02 -0700
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-29 07:21 -0700
    Re: PLASMA 2.0 "Frank M." <frank_o_rama@hotmail.com> - 2018-03-29 08:25 -0700
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-29 22:21 -0700
      Re: PLASMA 2.0 "Frank M." <frank_o_rama@hotmail.com> - 2018-04-01 07:48 -0700
        Re: PLASMA 2.0 "Michael J. Mahon" <mjmahon@aol.com> - 2018-04-01 13:12 -0700
          Re: PLASMA 2.0 Brian Patrie <bpatrie@bellsouth.spamisicky.net> - 2018-04-02 00:02 -0500
            Re: PLASMA 2.0 Brian Patrie <bpatrie@bellsouth.spamisicky.net> - 2018-04-03 00:07 -0500
              Re: PLASMA 2.0 MG <guidero@gmail.com> - 2018-04-02 22:35 -0700
              Re: PLASMA 2.0 Michael J. Mahon <mjmahon@aol.com> - 2018-04-03 13:47 -0500
                Re: PLASMA 2.0 Brian Patrie <bpatrie@bellsouth.spamisicky.net> - 2018-04-04 04:38 -0500
    Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-30 15:46 -0700
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-03-31 13:25 -0700
    Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-04-12 18:43 -0700
    Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-04-14 08:43 -0700
      Re: PLASMA 2.0 Michael J. Mahon <mjmahon@aol.com> - 2018-04-14 21:26 -0500
        Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-04-15 07:35 -0700
          Re: PLASMA 2.0 "Michael J. Mahon" <mjmahon@aol.com> - 2018-04-15 16:24 -0700
            Re: PLASMA 2.0 Michael Pohoreski <michael.pohoreski@gmail.com> - 2018-04-23 23:01 -0700
      Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-04-15 00:24 -0700
        Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-04-15 08:10 -0700
          Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-04-15 10:22 -0700
            Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-04-15 13:00 -0700
              Re: PLASMA 2.0 John Brooks <jbrooks@blueshiftinc.com> - 2018-04-15 15:17 -0700
    PLASMA 2.0 Michael Pohoreski <michael.pohoreski@gmail.com> - 2018-04-24 08:54 -0700
      Re: PLASMA 2.0 David Schmenk <dschmenk@gmail.com> - 2018-04-25 06:37 -0700

Page 3 of 3 — ← Prev page 1 2 [3]


#4489

FromBrian Patrie <bpatrie@bellsouth.spamisicky.net>
Date2018-04-03 00:07 -0500
Message-ID<p9v278$bdu$1@gioia.aioe.org>
In reply to#4488
On 2018-04-02 00:02, Brian Patrie wrote:
> On 2018-04-01 15:12, Michael J. Mahon wrote:
>  > if the global page date or time is zero,
>  > then a ProDOS-compatible clock is not present.
> 
> Well, if the date is zero.
> If the time is zero, it might just be midnight.  :)

Come to think of it, it's also worth mentioning that the presence of a 
valid date and time should not be taken as evidence of a real-time 
clock, as it can be set manually.

[toc] | [prev] | [next] | [standalone]


#4490

FromMG <guidero@gmail.com>
Date2018-04-02 22:35 -0700
Message-ID<97998729-b119-4c12-bac9-da8ad3186633@googlegroups.com>
In reply to#4489
On Monday, April 2, 2018 at 10:07:53 PM UTC-7, Brian Patrie wrote:
> Come to think of it, it's also worth mentioning that the presence of a 
> valid date and time should not be taken as evidence of a real-time 
> clock, as it can be set manually.


Just to pile on, the "proper" way to determine if a ProDOS-compatible clock is present is to check MACHID bit 0 = 1.  Also, if $BF06 is not $60 (an RTS) there's a high likelihood that a clock driver is installed.

But... even if MACHID bit 0 = 0 and $BF06 is $60, there is at least one case where you may still have accurate ProDOS date/time:  If there is an Apple II Workstation card present and logged into an AFP server the date and time will be updated by querying the server, but only if MACHID bit 0 is 0. 

MG

[toc] | [prev] | [next] | [standalone]


#4491

FromMichael J. Mahon <mjmahon@aol.com>
Date2018-04-03 13:47 -0500
Message-ID<MtqdnUr0O5G4UV7HnZ2dnUU7-bfNnZ2d@giganews.com>
In reply to#4489
Brian Patrie <bpatrie@bellsouth.spamisicky.net> wrote:
> On 2018-04-02 00:02, Brian Patrie wrote:
>> On 2018-04-01 15:12, Michael J. Mahon wrote:
>>> if the global page date or time is zero,
>>> then a ProDOS-compatible clock is not present.
>> 
>> Well, if the date is zero.
>> If the time is zero, it might just be midnight.  :)
> 
> Come to think of it, it's also worth mentioning that the presence of a 
> valid date and time should not be taken as evidence of a real-time 
> clock, as it can be set manually.
> 

Right. It’s just a heuristic—I’d guess it’s right in the vast majority of
cases. 

Apple actually suggested the possibility of the user setting the date/time
bytes as a way to get ProDOS to time/date stamp files to a user-selected
value. 

-- 
-michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com

[toc] | [prev] | [next] | [standalone]


#4492

FromBrian Patrie <bpatrie@bellsouth.spamisicky.net>
Date2018-04-04 04:38 -0500
Message-ID<pa26dv$1vnm$1@gioia.aioe.org>
In reply to#4491
On 2018-04-03 13:47, Michael J. Mahon wrote:
> Brian Patrie <bpatrie@bellsouth.spamisicky.net> wrote:
>> On 2018-04-02 00:02, Brian Patrie wrote:
>>> On 2018-04-01 15:12, Michael J. Mahon wrote:
>>>> if the global page date or time is zero,
>>>> then a ProDOS-compatible clock is not present.
>>>
>>> Well, if the date is zero.
>>> If the time is zero, it might just be midnight.  :)
>>
>> Come to think of it, it's also worth mentioning that the presence of a
>> valid date and time should not be taken as evidence of a real-time
>> clock, as it can be set manually.
> 
> Right. It’s just a heuristic—I’d guess it’s right in the vast majority of
> cases.
> 
> Apple actually suggested the possibility of the user setting the date/time
> bytes as a way to get ProDOS to time/date stamp files to a user-selected
> value.

Yup.  I did that, routinely, before i got a No-Slot-Clock.  Wrote a 
doohickey that remembered the last date, so all i had to do was tweak 
it.  (Lost to the sands of time and disk failure, sadly.)

[toc] | [prev] | [next] | [standalone]


#4484

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-03-30 15:46 -0700
Message-ID<ce1636f8-84f1-4631-83bb-7e04d67a24eb@googlegroups.com>
In reply to#4358
After much code crunching, I have the JIT compiler down to an 8K module. By combining the code generation for similar opcodes, it all meets my original goal, barely. Seriously, it's (8K - 8) bytes in size. And I also re-worked the optimization strategy for the Y register. Now, its value is tracked, with a pre-disposotion to getting to to zero, but not forcing it. The Y register gets thrashed often when loading and saving local variables to the frame stack, but the local variable with offset zero is far ana away the most common case. And zero is handy for filling the MSB of byte values. So the code generation is a little improved, and about as goood as one can expect from an 8K compiler. Perhaps I'll write up the technique with some examples.

If you would like to try it out, I've updated the disk images. On your 128K Apple //e or //c, launch the PLAJIT.SYSTEM (I need a better name, maybe IJIT.SYSTEM) program and you will see the JIT Compiler loaded message. I've since removed one of the tuneable parameters since it didn't seem to do any good and made the VM entrypoint ugly. The default values are best for running real programs like the compiler and editor. But for benchmarks, they have to be tweaked. Run '+JITUNE 1' to set the call count to 1 before calling the JIT compiler. This basically compiles every routine it can, the first time it sees it. Here are a few things to try:

Build and run Rod's Colors
'P BLD'
'+JITUNE 45 255' - Only if you've already played around with the default values
'+PLASM -O2 ROD.PLA'
'+ROD'
'+JITUNE 1'
'+ROD'

Notice the difference in speed between the two instances of running ROD.

Check compile speed
'P BLD'
'+JITUNE 45 0' - Effectively disable JIT compilation for any routine (max size = 0)
'+PLASM RPNCALC.PLA' - Time the duration (takes awhile)
'+JITUNE 45 255' - Reenable default JIT values
'+PLASM RPNCALC.PLA' - Compare time with above

It's interesting running the JIT compiler on the PLASMA compiler, PLASM. I had previously rewritten the lowest level of the compiler, the part that parses the variable names and keywords, in assembly for a nice performance improvement. Even with that optimization in place, the JIT compiler is able to extract almost 2X the performance from the remaining bytecode.

The other interesting benchmark is SIEVE.PLA. Note that the source code included prints out all te primes as they're calculated. If you remove the prints statements in the editor (CTRL-X on the line containing PUTI and PUTLN), then compile with: '+PLASM -O2 SIEVE.PLA' you can see the big difference the JIT compiler can make on pure PLASMA code (don't forget '+JITUNE 1'). About 4X by my measurements.

Download the ProDOS disk images here: https://github.com/dschmenk/PLASMA/tree/devel

Note: this is the version 2 devel branch, so the image names have been update, i.e. PLASMA-SYS2.PO

Everything else from Version 1 applies here.

Dave...

[toc] | [prev] | [next] | [standalone]


#4485

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-03-31 13:25 -0700
Message-ID<a6e85791-e395-44e4-aa79-e188b95f25c1@googlegroups.com>
In reply to#4484
A first stab at describing the PLASMA JIT compilation process: https://github.com/dschmenk/PLASMA/wiki/PLASMA-JIT-Compiler-Implementation

[toc] | [prev] | [next] | [standalone]


#4497

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-04-12 18:43 -0700
Message-ID<527909d1-d83c-4d4a-8359-b58a3e4a6d74@googlegroups.com>
In reply to#4358
The PLASMA JIT compiler for the 6502 has now been joined by a 65802/65816 JIT compiler. PLASMA bytecode modules are compiled on-the-fly into the proper machine code depending on the CPU. The JIT compilers are now available for hte Apple II, Apple III, and IIGS/65802 upgraded machines.

I haven't done any performance measurements on the 65802, yet. The generated code is much more efficient than the 6502, as the PLASMA VM is a 16 bit architecture that maps well to the 65802. The only mismatch is when entering, returning, or calling routines. The evaluation stack in Zero Page has to be mapped to the 65802 hardware stack. As a result, performance will be affected by the number of function calls made.

The JIT compilers are available here for your perusal:

6502 core - https://github.com/dschmenk/PLASMA/blob/master/src/libsrc/jitcore.pla

65802 core - https://github.com/dschmenk/PLASMA/blob/master/src/libsrc/jit16core.pla

This pretty much wraps up the new technology for PLASMA 2.0. Now time to work through all the libraries and sample code to make sure it works with the JIT compilers and architectural updates. And port to more machines. Steve F is working on updating the Beeb port and there should be a C64 version, too.

Dave...

[toc] | [prev] | [next] | [standalone]


#4498

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-04-14 08:43 -0700
Message-ID<a5c869e7-d333-4eba-8836-a16dd3af1680@googlegroups.com>
In reply to#4358
Here are some quick resuls for the latest PLASMA VM and JIT compiler optiizations. I moved to testing on an Apple II GS (for the 65816 CPU) running at 1 MHz. I'm only interested in relative times, and running at 1 MHz should make my wall clock timing more accurate and somewhat comparable to the previous timings from an Apple //e. My Apple IIGS does have a CFFA 3000, so the I/O overhead is about as minimal as you can get on real hardware.

The test run is the PLASM compiler compiling the RPNCALC.PLA source - a reasonably sophisticated program. This used to be a painful exercise on real, unaccelerated hardware.

The two VMs, the 65802/65816 specific VM, and the 6502/65C02 specific VM are timed, both with the JIT compiler enabled with default values and with the JIT compiler effectively disabled by setting the maximum JIT compileable routine size to zero.

Test: +PLASM RPNCALC.PLA

6502  No JIT: 95.45 s (baseline)
6502     JIT: 51.41 s (46% speed improvement over 6502  No JIT)
                      (37% speed improvement over 65802 No JIT)
                      
65802 No JIT: 81.52 s (15% speed improvement over 6502  No JIT)
65802    JIT: 41.50 s (49% speed improvement over 65802 No JIT)
                      (57% speed improvement over 6502  No JIT)
                      (19% speed improvement over 6502     JIT)


What I like about this test is that it's a real-word test. It includes I/O overhead and wasn't tuned to be a benchmark. Whatever the JIT compiler deemed to be important is what got optimized without any input from me (except for the default JIT parameters which I previously determined experimentally).

The same JIT parameters are used for both the 6502 and 65802 JIT compilers. I did a quick test changing the values for the 65802 JIT compiler, but it seemed to like the same values used for the 6502 JIT compiler. And this with a completely different machine code architecture - the 65802 version uses the hardware stack for evaluation and generates much smaller code. I'm guessing the code buffer can fit more compiled routines due to its higher code density. The 65802 does have to do more work to map the Zero Page evaluation stack to the hardware stack on entry/exit, though.

I'm stil blown away by how small a code buffer can make such an improvement. On my 8 MHz Apple //c with 65802 and 1 MB RAMDISK, the compiles fly. Feels like Turbo Pascal vs Apple Pascal.

I've updated the disk images with the latest VMs. When booting the PLASMA-SYS2.PO image, it will automatically detect the system and launch the best VM for the hardware: https://github.com/dschmenk/PLASMA

Lastly, I've updated the bytecode definition chart to Version 2.0. You can see how the bytecodes get executed in the VMs and how the JIT compilers convert them the machine code: https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes

 Dave...

[toc] | [prev] | [next] | [standalone]


#4499

FromMichael J. Mahon <mjmahon@aol.com>
Date2018-04-14 21:26 -0500
Message-ID<oZWdndlon8TDJU_HnZ2dnUU7-XlQAAAA@giganews.com>
In reply to#4498
David Schmenk <dschmenk@gmail.com> wrote:
> Here are some quick resuls for the latest PLASMA VM and JIT compiler
> optiizations. I moved to testing on an Apple II GS (for the 65816 CPU)
> running at 1 MHz. I'm only interested in relative times, and running at 1
> MHz should make my wall clock timing more accurate and somewhat
> comparable to the previous timings from an Apple //e. My Apple IIGS does
> have a CFFA 3000, so the I/O overhead is about as minimal as you can get on real hardware.
> 
> The test run is the PLASM compiler compiling the RPNCALC.PLA source - a
> reasonably sophisticated program. This used to be a painful exercise on
> real, unaccelerated hardware.
> 
> The two VMs, the 65802/65816 specific VM, and the 6502/65C02 specific VM
> are timed, both with the JIT compiler enabled with default values and
> with the JIT compiler effectively disabled by setting the maximum JIT
> compileable routine size to zero.
> 
> Test: +PLASM RPNCALC.PLA
> 
> 6502  No JIT: 95.45 s (baseline)
> 6502     JIT: 51.41 s (46% speed improvement over 6502  No JIT)
>                       (37% speed improvement over 65802 No JIT)
>                       
> 65802 No JIT: 81.52 s (15% speed improvement over 6502  No JIT)
> 65802    JIT: 41.50 s (49% speed improvement over 65802 No JIT)
>                       (57% speed improvement over 6502  No JIT)
>                       (19% speed improvement over 6502     JIT)
> 
> 
> What I like about this test is that it's a real-word test. It includes
> I/O overhead and wasn't tuned to be a benchmark. Whatever the JIT
> compiler deemed to be important is what got optimized without any input
> from me (except for the default JIT parameters which I previously
> determined experimentally).
> 
> The same JIT parameters are used for both the 6502 and 65802 JIT
> compilers. I did a quick test changing the values for the 65802 JIT
> compiler, but it seemed to like the same values used for the 6502 JIT
> compiler. And this with a completely different machine code architecture
> - the 65802 version uses the hardware stack for evaluation and generates
> much smaller code. I'm guessing the code buffer can fit more compiled
> routines due to its higher code density. The 65802 does have to do more
> work to map the Zero Page evaluation stack to the hardware stack on entry/exit, though.
> 
> I'm stil blown away by how small a code buffer can make such an
> improvement. On my 8 MHz Apple //c with 65802 and 1 MB RAMDISK, the
> compiles fly. Feels like Turbo Pascal vs Apple Pascal.
> 
> I've updated the disk images with the latest VMs. When booting the
> PLASMA-SYS2.PO image, it will automatically detect the system and launch
> the best VM for the hardware: https://github.com/dschmenk/PLASMA
> 
> Lastly, I've updated the bytecode definition chart to Version 2.0. You
> can see how the bytecodes get executed in the VMs and how the JIT
> compilers convert them the machine code:
> https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes
> 
>  Dave...
> 

Very nice work, Dave!

Congratulations!

-- 
-michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com

[toc] | [prev] | [next] | [standalone]


#4501

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-04-15 07:35 -0700
Message-ID<3575b5c3-a77b-4e05-a30d-76768e576880@googlegroups.com>
In reply to#4499
On Saturday, 14 April 2018 19:26:44 UTC-7, mjm...@aol.com  wrote:
> David Schmenk <dschmenk@gmail.com> wrote:
> > Here are some quick resuls for the latest PLASMA VM and JIT compiler
> > optiizations. I moved to testing on an Apple II GS (for the 65816 CPU)
> > running at 1 MHz. I'm only interested in relative times, and running at 1
> > MHz should make my wall clock timing more accurate and somewhat
> > comparable to the previous timings from an Apple //e. My Apple IIGS does
> > have a CFFA 3000, so the I/O overhead is about as minimal as you can get on real hardware.
> > 
> > The test run is the PLASM compiler compiling the RPNCALC.PLA source - a
> > reasonably sophisticated program. This used to be a painful exercise on
> > real, unaccelerated hardware.
> > 
> > The two VMs, the 65802/65816 specific VM, and the 6502/65C02 specific VM
> > are timed, both with the JIT compiler enabled with default values and
> > with the JIT compiler effectively disabled by setting the maximum JIT
> > compileable routine size to zero.
> > 
> > Test: +PLASM RPNCALC.PLA
> > 
> > 6502  No JIT: 95.45 s (baseline)
> > 6502     JIT: 51.41 s (46% speed improvement over 6502  No JIT)
> >                       (37% speed improvement over 65802 No JIT)
> >                       
> > 65802 No JIT: 81.52 s (15% speed improvement over 6502  No JIT)
> > 65802    JIT: 41.50 s (49% speed improvement over 65802 No JIT)
> >                       (57% speed improvement over 6502  No JIT)
> >                       (19% speed improvement over 6502     JIT)
> > 
> > 
> > What I like about this test is that it's a real-word test. It includes
> > I/O overhead and wasn't tuned to be a benchmark. Whatever the JIT
> > compiler deemed to be important is what got optimized without any input
> > from me (except for the default JIT parameters which I previously
> > determined experimentally).
> > 
> > The same JIT parameters are used for both the 6502 and 65802 JIT
> > compilers. I did a quick test changing the values for the 65802 JIT
> > compiler, but it seemed to like the same values used for the 6502 JIT
> > compiler. And this with a completely different machine code architecture
> > - the 65802 version uses the hardware stack for evaluation and generates
> > much smaller code. I'm guessing the code buffer can fit more compiled
> > routines due to its higher code density. The 65802 does have to do more
> > work to map the Zero Page evaluation stack to the hardware stack on entry/exit, though.
> > 
> > I'm stil blown away by how small a code buffer can make such an
> > improvement. On my 8 MHz Apple //c with 65802 and 1 MB RAMDISK, the
> > compiles fly. Feels like Turbo Pascal vs Apple Pascal.
> > 
> > I've updated the disk images with the latest VMs. When booting the
> > PLASMA-SYS2.PO image, it will automatically detect the system and launch
> > the best VM for the hardware: https://github.com/dschmenk/PLASMA
> > 
> > Lastly, I've updated the bytecode definition chart to Version 2.0. You
> > can see how the bytecodes get executed in the VMs and how the JIT
> > compilers convert them the machine code:
> > https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes
> > 
> >  Dave...
> > 
> 
> Very nice work, Dave!
> 
> Congratulations!
> 
> -- 
> -michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com

Thanks Michael - This is what I envisioned PLASMA to be all those years ago when I threw the towel in on the Java VM. The result has exceeded my expectations and I've learned a great deal along the way, i.e. the JIT compiler has been a series of epiphanies.

In fact, the JIT compiler has been more of an exercise in what *not* to compile. I even added a module flag to signal the loader to keep the code from being JIT compiled. The text editor, for instance, would halt for a split second when one of its routines would get compiled, possibly losing a keystroke. Now, I'm a horrible typist, but this was even annoying me! There really was no need to compile the wait-for-keypress routine, so I added the no-jit flag.

Someday I need to integrate a profiler into the VM, but I keep running into the memory limitations of such a small system. All in due time.

I think the concept of a VM and JIT compiler has some actual usefulness to modern embedded designs, especially in regard to the IoTs. Wouldn't it be funny to publish a paper using an Apple II as a prototype for an IoT design.

Dave...

[toc] | [prev] | [next] | [standalone]


#4506

From"Michael J. Mahon" <mjmahon@aol.com>
Date2018-04-15 16:24 -0700
Message-ID<DOKdnU8MCNncQk7HnZ2dnUU7-XXNnZ2d@giganews.com>
In reply to#4501
On 4/15/2018 7:35 AM, David Schmenk wrote:
> On Saturday, 14 April 2018 19:26:44 UTC-7, mjm...@aol.com  wrote:
>> David Schmenk <dschmenk@gmail.com> wrote:
>>> Here are some quick resuls for the latest PLASMA VM and JIT compiler
>>> optiizations. I moved to testing on an Apple II GS (for the 65816 CPU)
>>> running at 1 MHz. I'm only interested in relative times, and running at 1
>>> MHz should make my wall clock timing more accurate and somewhat
>>> comparable to the previous timings from an Apple //e. My Apple IIGS does
>>> have a CFFA 3000, so the I/O overhead is about as minimal as you can get on real hardware.
>>>
>>> The test run is the PLASM compiler compiling the RPNCALC.PLA source - a
>>> reasonably sophisticated program. This used to be a painful exercise on
>>> real, unaccelerated hardware.
>>>
>>> The two VMs, the 65802/65816 specific VM, and the 6502/65C02 specific VM
>>> are timed, both with the JIT compiler enabled with default values and
>>> with the JIT compiler effectively disabled by setting the maximum JIT
>>> compileable routine size to zero.
>>>
>>> Test: +PLASM RPNCALC.PLA
>>>
>>> 6502  No JIT: 95.45 s (baseline)
>>> 6502     JIT: 51.41 s (46% speed improvement over 6502  No JIT)
>>>                        (37% speed improvement over 65802 No JIT)
>>>                        
>>> 65802 No JIT: 81.52 s (15% speed improvement over 6502  No JIT)
>>> 65802    JIT: 41.50 s (49% speed improvement over 65802 No JIT)
>>>                        (57% speed improvement over 6502  No JIT)
>>>                        (19% speed improvement over 6502     JIT)
>>>
>>>
>>> What I like about this test is that it's a real-word test. It includes
>>> I/O overhead and wasn't tuned to be a benchmark. Whatever the JIT
>>> compiler deemed to be important is what got optimized without any input
>>> from me (except for the default JIT parameters which I previously
>>> determined experimentally).
>>>
>>> The same JIT parameters are used for both the 6502 and 65802 JIT
>>> compilers. I did a quick test changing the values for the 65802 JIT
>>> compiler, but it seemed to like the same values used for the 6502 JIT
>>> compiler. And this with a completely different machine code architecture
>>> - the 65802 version uses the hardware stack for evaluation and generates
>>> much smaller code. I'm guessing the code buffer can fit more compiled
>>> routines due to its higher code density. The 65802 does have to do more
>>> work to map the Zero Page evaluation stack to the hardware stack on entry/exit, though.
>>>
>>> I'm stil blown away by how small a code buffer can make such an
>>> improvement. On my 8 MHz Apple //c with 65802 and 1 MB RAMDISK, the
>>> compiles fly. Feels like Turbo Pascal vs Apple Pascal.
>>>
>>> I've updated the disk images with the latest VMs. When booting the
>>> PLASMA-SYS2.PO image, it will automatically detect the system and launch
>>> the best VM for the hardware: https://github.com/dschmenk/PLASMA
>>>
>>> Lastly, I've updated the bytecode definition chart to Version 2.0. You
>>> can see how the bytecodes get executed in the VMs and how the JIT
>>> compilers convert them the machine code:
>>> https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes
>>>
>>>   Dave...
>>>
>>
>> Very nice work, Dave!
>>
>> Congratulations!
>>
>> -- 
>> -michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com
> 
> Thanks Michael - This is what I envisioned PLASMA to be all those years ago when I threw the towel in on the Java VM. The result has exceeded my expectations and I've learned a great deal along the way, i.e. the JIT compiler has been a series of epiphanies.
> 
> In fact, the JIT compiler has been more of an exercise in what *not* to compile. I even added a module flag to signal the loader to keep the code from being JIT compiled. The text editor, for instance, would halt for a split second when one of its routines would get compiled, possibly losing a keystroke. Now, I'm a horrible typist, but this was even annoying me! There really was no need to compile the wait-for-keypress routine, so I added the no-jit flag.
> 
> Someday I need to integrate a profiler into the VM, but I keep running into the memory limitations of such a small system. All in due time.
> 
> I think the concept of a VM and JIT compiler has some actual usefulness to modern embedded designs, especially in regard to the IoTs. Wouldn't it be funny to publish a paper using an Apple II as a prototype for an IoT design.
> 
> Dave...

That would be GREAT! ;-)

I second your observation that knowing what NOT to compile is key.  In 
most system programs, and many interactive programs, a substantial 
fraction of the code is error handling, and it's never useful to compile 
a routine that's called seldom or never.

This was the key realization of profile-directed optimization. (Another 
was that in a world of separately compiled modules, only at runtime do 
you have enough information to know what to spend compiler/optimizer 
time on.)

-- 

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page: http://michaeljmahon.com

"The wastebasket is our most important design
tool--and it's seriously underused."

[toc] | [prev] | [next] | [standalone]


#4525

FromMichael Pohoreski <michael.pohoreski@gmail.com>
Date2018-04-23 23:01 -0700
Message-ID<2d743f1e-193b-4c94-a33d-f67d16eefee3@googlegroups.com>
In reply to#4506
> This was the key realization of profile-directed optimization. (Another 
> was that in a world of separately compiled modules, only at runtime do 
> you have enough information to know what to spend compiler/optimizer 
> time on.) 

To expand on this concept.

In the toolchain "ecosystem", each tool only has _partial_ information that if it was possible to relay this information to the other components, then all the OTHER tools could make better informed decisions.

Here is a different paradigm on how to view the entire toolchain:

        Editor
           ^
           |
Compiler <-+-> Profiler
           |
           v
         Version Control


Pretend "Debugger" is another spoke in the "wheel".

What's at the core?  (+) is a Database of common knowledge that any tool can query / set.

Examples:

1. Your editor knows which lines were changed except they don't pass this to the compiler. There is little point in (re) compiling EVERYTHING when typically only a few lines have changed.  Sadly, "incremental compilation" never caught on, and compilers have remained stupid ever since.  A tiny change in a structure forces it to recompile everything instead of querying the database in the center for what functions are _actually_ needed to be compiled.

Worse, editors end up duplicate the parsing of the language that the compiler also does. They are unable to pass the Abstract Syntax Tree to the compiler.

2. Only at run-time does the profiler know which functions are "hot" or "cold".  Passing this information to compiler helps optimization for size or speed.  

Same thing for the Class Hierarchy.  Only at run time do you actually know _which_ virtual functions are really needed.  

A "hard example": Unfortunately C++ is a brain-dead language which doesn't understand the "double dispatch" pattern so programmers are forced to cover "all paths" -- although with Template Meta-Programming you can work around some of this and provide partial template specialization but then your complexity just shot up like crazy.

3. The version control system know which files are likely to be modified next based on past history. It could tell the compiler to start pre-compiling and/or to store that information in a temporary fashion since it will most likely be modified.

4. Due to heavy optimizations the debugger has a hard time keeping track of the "life cycle" of a variable.  If the compiler kept better stats about how it optimized a variable and the data flow, a debugger would be able to provide better annotation on a per opcode basis.

You can typically see how brain-dead debuggers are when they don't understand how to place multiple breakpoints on the same line.  This in turn forces programmers to write common code spread across multiple lines when the common code could be written in a more 2D fashion.

I've never seen anyone replace the Linear edit-compile-debug-profile-versioning with a Non-Linear holistic paradigm.  Instead we are stuck with an archaic linear paradigm with hacks and kludges to share information, and gimped tools. :-/

You can tell I've thought about this before. :-)

[toc] | [prev] | [next] | [standalone]


#4500

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-04-15 00:24 -0700
Message-ID<787035e9-1b7c-4f62-8559-f9ec9c9dcb9d@googlegroups.com>
In reply to#4498
On Saturday, April 14, 2018 at 8:43:49 AM UTC-7, David Schmenk wrote:
> Here are some quick resuls for the latest PLASMA VM and JIT compiler optiizations. I moved to testing on an Apple II GS (for the 65816 CPU) running at 1 MHz. I'm only interested in relative times, and running at 1 MHz should make my wall clock timing more accurate and somewhat comparable to the previous timings from an Apple //e. My Apple IIGS does have a CFFA 3000, so the I/O overhead is about as minimal as you can get on real hardware.
> 
> The test run is the PLASM compiler compiling the RPNCALC.PLA source - a reasonably sophisticated program. This used to be a painful exercise on real, unaccelerated hardware.
> 
> The two VMs, the 65802/65816 specific VM, and the 6502/65C02 specific VM are timed, both with the JIT compiler enabled with default values and with the JIT compiler effectively disabled by setting the maximum JIT compileable routine size to zero.
> 
> Test: +PLASM RPNCALC.PLA
> 
> 6502  No JIT: 95.45 s (baseline)
> 6502     JIT: 51.41 s (46% speed improvement over 6502  No JIT)
>                       (37% speed improvement over 65802 No JIT)
>                       
> 65802 No JIT: 81.52 s (15% speed improvement over 6502  No JIT)
> 65802    JIT: 41.50 s (49% speed improvement over 65802 No JIT)
>                       (57% speed improvement over 6502  No JIT)
>                       (19% speed improvement over 6502     JIT)
> 
> 
> What I like about this test is that it's a real-word test. It includes I/O overhead and wasn't tuned to be a benchmark. Whatever the JIT compiler deemed to be important is what got optimized without any input from me (except for the default JIT parameters which I previously determined experimentally).
> 
> The same JIT parameters are used for both the 6502 and 65802 JIT compilers. I did a quick test changing the values for the 65802 JIT compiler, but it seemed to like the same values used for the 6502 JIT compiler. And this with a completely different machine code architecture - the 65802 version uses the hardware stack for evaluation and generates much smaller code. I'm guessing the code buffer can fit more compiled routines due to its higher code density. The 65802 does have to do more work to map the Zero Page evaluation stack to the hardware stack on entry/exit, though.
> 
> I'm stil blown away by how small a code buffer can make such an improvement. On my 8 MHz Apple //c with 65802 and 1 MB RAMDISK, the compiles fly. Feels like Turbo Pascal vs Apple Pascal.
> 
> I've updated the disk images with the latest VMs. When booting the PLASMA-SYS2.PO image, it will automatically detect the system and launch the best VM for the hardware: https://github.com/dschmenk/PLASMA
> 
> Lastly, I've updated the bytecode definition chart to Version 2.0. You can see how the bytecodes get executed in the VMs and how the JIT compilers convert them the machine code: https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes
> 
>  Dave...

Great stuff Dave!

I've been away on other projects, but I browsed through 2.0 and made some notes:

plvm02.s:

1) If there was:
        STA     ESTKH+1,X
before DROP, it could be used by ADD,SUB, etc and save about 16 code bytes at the cost of 2 ZP bytes

2) Could NATV be:
NATV    TYA                     ; FLATTEN IP
        SEC
        ADC     IPL
        STA     IPL
        BCC     +
        INC     IPH
+       JMP     (IP)

3) Could the EOR #$FF in ENTER be calculated by the compiler instead of at runtime?
ENTER   INY
        LDA     (IP),Y
        EOR     #$FF

4) Could CALL and ICAL avoid saving & restoring IP?

5) Would 8-bit operations be ~2x faster if they used 8-bit opcodes instead of promoting to 16-bit opcodes?

6) Would it be worth adding immediate opcodes for XOR,SHL,SHR?


plvm802.s:

1) Would it be faster to use an eval stack with DP,X addressing instead of stack addressing?

2) Save some cycles & bytes in these opcode handlers:
NEG     PLA
        EOR     #$FFFF
        INC
        PHA
        JMP     NEXTOP

DECR    PLA
        DEC
        PHA
        JMP     NEXTOP

COMP    PLA
        EOR     #$FFFF
        PHA
        JMP     NEXTOP

SHL     PLX
        BEQ     +
        PLA
-       ASL
        DEX
        BNE     -
        PHA
+       JMP     NEXTOP

SHR     PLX
        BEQ     +
        PLA
-       CMP     #$8000
        ROR
        DEX
        BNE     -
        PHA
+       JMP     NEXTOP

SUBI    INY                     ;+INC_IP
        LDA     (IP),Y    ;Compiler does EOR #$FF
        ORA     #$FF00
        SEC
        ADC     TOS,S
        STA     TOS,S
        JMP     NEXTOP


DECBRGE PLA
        DEC
        PHA

INCBRLE PLA
        INC
        PHA

3) If IP was kept in Y reg, opcode loads could be faster by using DP $00,Y or ABS $0000,Y instead of (IP),Y


Fun stuff!

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4502

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-04-15 08:10 -0700
Message-ID<0fb7599d-bb60-42a0-accb-76d0ba36b3fd@googlegroups.com>
In reply to#4500
On Sunday, 15 April 2018 00:24:25 UTC-7, John Brooks  wrote:
> On Saturday, April 14, 2018 at 8:43:49 AM UTC-7, David Schmenk wrote:
> > Here are some quick resuls for the latest PLASMA VM and JIT compiler optiizations. I moved to testing on an Apple II GS (for the 65816 CPU) running at 1 MHz. I'm only interested in relative times, and running at 1 MHz should make my wall clock timing more accurate and somewhat comparable to the previous timings from an Apple //e. My Apple IIGS does have a CFFA 3000, so the I/O overhead is about as minimal as you can get on real hardware.
> > 
> > The test run is the PLASM compiler compiling the RPNCALC.PLA source - a reasonably sophisticated program. This used to be a painful exercise on real, unaccelerated hardware.
> > 
> > The two VMs, the 65802/65816 specific VM, and the 6502/65C02 specific VM are timed, both with the JIT compiler enabled with default values and with the JIT compiler effectively disabled by setting the maximum JIT compileable routine size to zero.
> > 
> > Test: +PLASM RPNCALC.PLA
> > 
> > 6502  No JIT: 95.45 s (baseline)
> > 6502     JIT: 51.41 s (46% speed improvement over 6502  No JIT)
> >                       (37% speed improvement over 65802 No JIT)
> >                       
> > 65802 No JIT: 81.52 s (15% speed improvement over 6502  No JIT)
> > 65802    JIT: 41.50 s (49% speed improvement over 65802 No JIT)
> >                       (57% speed improvement over 6502  No JIT)
> >                       (19% speed improvement over 6502     JIT)
> > 
> > 
> > What I like about this test is that it's a real-word test. It includes I/O overhead and wasn't tuned to be a benchmark. Whatever the JIT compiler deemed to be important is what got optimized without any input from me (except for the default JIT parameters which I previously determined experimentally).
> > 
> > The same JIT parameters are used for both the 6502 and 65802 JIT compilers. I did a quick test changing the values for the 65802 JIT compiler, but it seemed to like the same values used for the 6502 JIT compiler. And this with a completely different machine code architecture - the 65802 version uses the hardware stack for evaluation and generates much smaller code. I'm guessing the code buffer can fit more compiled routines due to its higher code density. The 65802 does have to do more work to map the Zero Page evaluation stack to the hardware stack on entry/exit, though.
> > 
> > I'm stil blown away by how small a code buffer can make such an improvement. On my 8 MHz Apple //c with 65802 and 1 MB RAMDISK, the compiles fly. Feels like Turbo Pascal vs Apple Pascal.
> > 
> > I've updated the disk images with the latest VMs. When booting the PLASMA-SYS2.PO image, it will automatically detect the system and launch the best VM for the hardware: https://github.com/dschmenk/PLASMA
> > 
> > Lastly, I've updated the bytecode definition chart to Version 2.0. You can see how the bytecodes get executed in the VMs and how the JIT compilers convert them the machine code: https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes
> > 
> >  Dave...
> 

Hi John-

> Great stuff Dave!
> 

Thanks!

> I've been away on other projects, but I browsed through 2.0 and made some notes:
> 
> plvm02.s:
> 
> 1) If there was:
>         STA     ESTKH+1,X
> before DROP, it could be used by ADD,SUB, etc and save about 16 code bytes at the cost of 2 ZP bytes
> 

This optimization could be useful for VMs that have to share limited RAM. I'll look into updating the Apple 1 version (and my soon to be discussed PLASMA computer).

> 2) Could NATV be:
> NATV    TYA                     ; FLATTEN IP
>         SEC
>         ADC     IPL
>         STA     IPL
>         BCC     +
>         INC     IPH
> +       JMP     (IP)
> 

Doh! Yep, what was I thinking? In fact, this important to the JIT compiled code, so I may even make it:

        BCS +
        JMP (IP)
+       INC IPH
        JMP (IP)

> 3) Could the EOR #$FF in ENTER be calculated by the compiler instead of at runtime?
> ENTER   INY
>         LDA     (IP),Y
>         EOR     #$FF
> 

Interesting. Something to look into


> 4) Could CALL and ICAL avoid saving & restoring IP?
> 

Generally, IP (the interpreter's Instruction Pointer) does have to be saved & restored for function calls, but potentially, not. If a machine language routine is being called, IP wouldn't need to be saved. Perhaps by moving the save/restore of IP to the VM entry & exit points, a saving could be made when calling native machine code. Now that the JIT compiler increases the number of native routines that get called. Hmmm....

> 5) Would 8-bit operations be ~2x faster if they used 8-bit opcodes instead of promoting to 16-bit opcodes?

Probably nowhere near 2x - so much overhead in other operations of the VM. However, I did make some big updates to the byte codes to take advantage of many 8 bit sequences. First, the immediate 8 bit operand versions of ADD, SUB, AND, OR really targeted the common cases. I also had the JIT compiler in mind when I added these, knowing they would compile into very efficient code. The other byte codes to ADD local and global variables (especially the BYTE sized ones) 
> 
> 6) Would it be worth adding immediate opcodes for XOR,SHL,SHR?
> 

The static analysis didn't show these to be particularly oft-used. In reality, neither was SUBI, bit I added it anyway just to be orthogonal ;-)

> 
> plvm802.s:
> 
> 1) Would it be faster to use an eval stack with DP,X addressing instead of stack addressing?
> 

The reason I went with stack addressing was the INX,INX/DEX,DEX that would be required for almost every operation. Those add up an annoying amount. For the 8 bit VM, I split the evaluation stack into MSB and LSB so it only had to do INX/DEX. But to have a 16 bit eval stack would require two per push/pop. However, it is possible I missed something with the 65802 (this is my first time coding the 65802/65816). Any thoughts?

> 2) Save some cycles & bytes in these opcode handlers:
> NEG     PLA
>         EOR     #$FFFF
>         INC
>         PHA
>         JMP     NEXTOP
> 
> DECR    PLA
>         DEC
>         PHA
>         JMP     NEXTOP
> 
> COMP    PLA
>         EOR     #$FFFF
>         PHA
>         JMP     NEXTOP
> 
> SHL     PLX
>         BEQ     +
>         PLA
> -       ASL
>         DEX
>         BNE     -
>         PHA
> +       JMP     NEXTOP
> 
> SHR     PLX
>         BEQ     +
>         PLA
> -       CMP     #$8000
>         ROR
>         DEX
>         BNE     -
>         PHA
> +       JMP     NEXTOP
> 
> SUBI    INY                     ;+INC_IP
>         LDA     (IP),Y    ;Compiler does EOR #$FF
>         ORA     #$FF00
>         SEC
>         ADC     TOS,S
>         STA     TOS,S
>         JMP     NEXTOP
> 
> 
> DECBRGE PLA
>         DEC
>         PHA
> 
> INCBRLE PLA
>         INC
>         PHA
> 

Damn, I thought I looked up LDA S,# vs PLA. Same speed, but PLA/PHA is smaller. Good thing the JIT compiler got it right ;-)

> 3) If IP was kept in Y reg, opcode loads could be faster by using DP $00,Y or ABS $0000,Y instead of (IP),Y

Another decision when moving to the 65802 that may or may not have been the right choice. I kept the index registers as 8 bits. I considered the exact scenario using Y as the full IP, but didn't due to accessing the local frame. With the 65802 JIT compiler, I re-thought everything and went with 16 bit index registers and I used the X register as the Frame Pointer and access the locals as DP LOCAL,X. Now I'm not going to sleep tonight thinking this over.

> 
> 
> Fun stuff!
> 
> -JB
> @JBrooksBSI

Once again, thanks for your incredible insights!

Dave...

[toc] | [prev] | [next] | [standalone]


#4503

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-04-15 10:22 -0700
Message-ID<45fac3df-222f-4462-878e-e85a59eafbb9@googlegroups.com>
In reply to#4502
> 4) Could CALL and ICAL avoid saving & restoring IP? 
> 
> Generally, IP (the interpreter's Instruction Pointer) does have to be saved & restored for function calls, but potentially, not. If a machine language routine is being called, IP wouldn't need to be saved. Perhaps by moving the save/restore of IP to the VM entry & exit points, a saving could be made when calling native machine code. Now that the JIT compiler increases the number of native routines that get called. Hmmm.... 

I was thinking the called native could could save/restore the IP ZP if needed. I assume most native code could just avoid using those ZP addresses. Also, if the native code used the ZP addresses of DROP, FETCH, etc, it would have to save/restore those ZP bytes anyway, right?


> Damn, I thought I looked up LDA S,# vs PLA. Same speed, but PLA/PHA is smaller. Good thing the JIT compiler got it right ;-) 

PHA is 1 cycle faster and 1 byte smaller than STA $xx,S.


> Another decision when moving to the 65802 that may or may not have been the right choice. I kept the index registers as 8 bits. I considered the exact scenario using Y as the full IP, but didn't due to accessing the local frame. With the 65802 JIT compiler, I re-thought everything and went with 16 bit index registers and I used the X register as the Frame Pointer and access the locals as DP LOCAL,X. Now I'm not going to sleep tonight thinking this over. 

I suspect the fastest approach would be to keep VM state in 3x 16-bit regs:

DP: Frame ptr
Y: IP
X: Eval stack ptr (relative to DP frame ptr)

allows:
1) INC/DEC DP,X for eval
2) Ptrs on eval stack can use (DP,X)
3) ABS,Y for IP
4) DP addressing for frame args
5) Ptr args on the local frame can use (DP),Y or 24-bit ptrs: [DP],Y
6) The stack could be used to push args onto either the eval stack or local frame

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4504

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-04-15 13:00 -0700
Message-ID<7485d762-f953-4a3d-9b20-ba96f2e51496@googlegroups.com>
In reply to#4503
On Sunday, 15 April 2018 10:22:20 UTC-7, John Brooks  wrote:
> > 4) Could CALL and ICAL avoid saving & restoring IP? 
> > 
> > Generally, IP (the interpreter's Instruction Pointer) does have to be saved & restored for function calls, but potentially, not. If a machine language routine is being called, IP wouldn't need to be saved. Perhaps by moving the save/restore of IP to the VM entry & exit points, a saving could be made when calling native machine code. Now that the JIT compiler increases the number of native routines that get called. Hmmm.... 
> 
> I was thinking the called native could could save/restore the IP ZP if needed. I assume most native code could just avoid using those ZP addresses. Also, if the native code used the ZP addresses of DROP, FETCH, etc, it would have to save/restore those ZP bytes anyway, right?
> 
> 
> > Damn, I thought I looked up LDA S,# vs PLA. Same speed, but PLA/PHA is smaller. Good thing the JIT compiler got it right ;-) 
> 
> PHA is 1 cycle faster and 1 byte smaller than STA $xx,S.
> 
> 
> > Another decision when moving to the 65802 that may or may not have been the right choice. I kept the index registers as 8 bits. I considered the exact scenario using Y as the full IP, but didn't due to accessing the local frame. With the 65802 JIT compiler, I re-thought everything and went with 16 bit index registers and I used the X register as the Frame Pointer and access the locals as DP LOCAL,X. Now I'm not going to sleep tonight thinking this over. 
> 
> I suspect the fastest approach would be to keep VM state in 3x 16-bit regs:
> 
> DP: Frame ptr
> Y: IP
> X: Eval stack ptr (relative to DP frame ptr)
> 
> allows:
> 1) INC/DEC DP,X for eval
> 2) Ptrs on eval stack can use (DP,X)
> 3) ABS,Y for IP
> 4) DP addressing for frame args
> 5) Ptr args on the local frame can use (DP),Y or 24-bit ptrs: [DP],Y
> 6) The stack could be used to push args onto either the eval stack or local frame
> 
> -JB
> @JBrooksBSI

I remember why I did it this way:

        INY                     ; NEXTOP @ $F0
        LDX     $FFFF,Y         ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
        JMP     (OPTBL,X)       ; OPIDX AND OPPAGE MAP OVER OPTBL

All about the opcode dispatch. One thing I found inconvenient with the architecture of the 65802/65816 was mixing byte access with word access. I would have preferred a size override prefix. When implementing the JIT compiler, the generated code keeps the TOS in A, and Frame Pointer in X (X can use an 8 bit DP address which is treated as an offset to the Frame Pointer, Y requires a 16 bit address). Y gets to float and used for temporaries. The accumulator rarely needs to be pushed or popped as it often gets immediately used for something.

I would definitely have done things differently if I was solely targeting the 65816. Maybe PLASMA 3.0.

Dave...

[toc] | [prev] | [next] | [standalone]


#4505

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-04-15 15:17 -0700
Message-ID<f573a3b3-fdb1-4ecf-b6ce-7342c478c773@googlegroups.com>
In reply to#4504
On Sunday, April 15, 2018 at 1:00:59 PM UTC-7, David Schmenk wrote:
> On Sunday, 15 April 2018 10:22:20 UTC-7, John Brooks  wrote:
> > > 4) Could CALL and ICAL avoid saving & restoring IP? 
> > > 
> > > Generally, IP (the interpreter's Instruction Pointer) does have to be saved & restored for function calls, but potentially, not. If a machine language routine is being called, IP wouldn't need to be saved. Perhaps by moving the save/restore of IP to the VM entry & exit points, a saving could be made when calling native machine code. Now that the JIT compiler increases the number of native routines that get called. Hmmm.... 
> > 
> > I was thinking the called native could could save/restore the IP ZP if needed. I assume most native code could just avoid using those ZP addresses. Also, if the native code used the ZP addresses of DROP, FETCH, etc, it would have to save/restore those ZP bytes anyway, right?
> > 
> > 
> > > Damn, I thought I looked up LDA S,# vs PLA. Same speed, but PLA/PHA is smaller. Good thing the JIT compiler got it right ;-) 
> > 
> > PHA is 1 cycle faster and 1 byte smaller than STA $xx,S.
> > 
> > 
> > > Another decision when moving to the 65802 that may or may not have been the right choice. I kept the index registers as 8 bits. I considered the exact scenario using Y as the full IP, but didn't due to accessing the local frame. With the 65802 JIT compiler, I re-thought everything and went with 16 bit index registers and I used the X register as the Frame Pointer and access the locals as DP LOCAL,X. Now I'm not going to sleep tonight thinking this over. 
> > 
> > I suspect the fastest approach would be to keep VM state in 3x 16-bit regs:
> > 
> > DP: Frame ptr
> > Y: IP
> > X: Eval stack ptr (relative to DP frame ptr)
> > 
> > allows:
> > 1) INC/DEC DP,X for eval
> > 2) Ptrs on eval stack can use (DP,X)
> > 3) ABS,Y for IP
> > 4) DP addressing for frame args
> > 5) Ptr args on the local frame can use (DP),Y or 24-bit ptrs: [DP],Y
> > 6) The stack could be used to push args onto either the eval stack or local frame
> > 
> > -JB
> > @JBrooksBSI
> 
> I remember why I did it this way:
> 
>         INY                     ; NEXTOP @ $F0
>         LDX     $FFFF,Y         ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
>         JMP     (OPTBL,X)       ; OPIDX AND OPPAGE MAP OVER OPTBL
> 
> All about the opcode dispatch. One thing I found inconvenient with the architecture of the 65802/65816 was mixing byte access with word access. I would have preferred a size override prefix. When implementing the JIT compiler, the generated code keeps the TOS in A, and Frame Pointer in X (X can use an 8 bit DP address which is treated as an offset to the Frame Pointer, Y requires a 16 bit address). Y gets to float and used for temporaries. The accumulator rarely needs to be pushed or popped as it often gets immediately used for something.
> 
> I would definitely have done things differently if I was solely targeting the 65816. Maybe PLASMA 3.0.
> 
> Dave...

Right. The 65816 can dedicate much of a 64K code bank to the opcode handlers, with each handler given $200 bytes. The dispatch would be 1-2 cycles slower than the 65802 code, but it prefetches IP+1 in AH, allows 16-bit XY, and X can be dedicated to an eval stack:

Current 8-bit XY approach = 15/16 cycle dispatch
OPHANDLER
...
3       JMP     NEXTOP
NEXTOP
2       INY                     ; NEXTOP @ $F0 
4/5     LDX     $FFFF,Y         ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2 
6        JMP     (OPTBL,X)       ; OPIDX AND OPPAGE MAP OVER OPTBL 
=15/16 cycles


16-bit XY approach = 17 cycle dispatch
OPHANDLER
...
2       INY
6       LDA     $0000,Y         ; IP IN Y REG. LOAD OP IN AH
6       STAL    MODOPJMP  ; MOD FOLLOWING JMP IN CODE BANK
3       JMP     OPJMP           ; $200 BYTES PER OP HANDLER
MODOPJMP EQU *-1
        DS      1
=17 cycles

-JB

[toc] | [prev] | [next] | [standalone]


#4528

FromMichael Pohoreski <michael.pohoreski@gmail.com>
Date2018-04-24 08:54 -0700
Message-ID<bbcfa250-ddf8-4ba6-aafe-5a8cb180bf88@googlegroups.com>
In reply to#4358
David,

Even though, personally, I'll probably never use PLASMA (6502 junkie) I want to say reading this thread has been fantastic!  It's great to see different optimizations discussed, implemented, and the actual stats on how it effected performance.

Please keep posting your work -- I'm sure there are others who are enjoying reading it as well.

Cheers
Michael

[toc] | [prev] | [next] | [standalone]


#4532

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-04-25 06:37 -0700
Message-ID<bac5cc76-1f16-4974-8fbc-0fcaffc8984d@googlegroups.com>
In reply to#4528
On Tuesday, 24 April 2018 08:54:26 UTC-7, Michael Pohoreski  wrote:
> David,
> 
> Even though, personally, I'll probably never use PLASMA (6502 junkie) I want to say reading this thread has been fantastic!  It's great to see different optimizations discussed, implemented, and the actual stats on how it effected performance.
> 
> Please keep posting your work -- I'm sure there are others who are enjoying reading it as well.
> 
> Cheers
> Michael

Thanks Michael-

PLASMA is about 35 years too late. But better late than never, right?

Dave...

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.sys.apple2.programmer


csiph-web