#define (from C) in Python

Discussion in 'Python' started by Santiago Romero, Nov 12, 2009.

  1. Is there a Python version of C's language #define statements?

    Example:

    #define ReadMem( (x) ) memory[ (x) ]

    Instead of using a function, when you call to ReadMem(), the code is
    INCLUDED, (no function is called, the "compiler" just substitues the
    ReadMem( expression ) with memory[ (expression) ] .

    I want to avoid function calls to speed up a program by sacrifizing
    the resulting size ...

    Is that possible?
     
    Santiago Romero, Nov 12, 2009
    #1
    1. Advertising

  2. Santiago Romero schrieb:
    > Is there a Python version of C's language #define statements?
    >
    > Example:
    >
    > #define ReadMem( (x) ) memory[ (x) ]
    >
    > Instead of using a function, when you call to ReadMem(), the code is
    > INCLUDED, (no function is called, the "compiler" just substitues the
    > ReadMem( expression ) with memory[ (expression) ] .
    >
    > I want to avoid function calls to speed up a program by sacrifizing
    > the resulting size ...
    >
    > Is that possible?


    Not without taking the extra step of a ... preprocessor. As C does.

    Diez
     
    Diez B. Roggisch, Nov 12, 2009
    #2
    1. Advertising

  3. On Nov 12, 5:43 pm, Santiago Romero <> wrote:
    > Is there a Python version of C's language #define statements?
    >
    > Example:
    >
    > #define ReadMem( (x) )    memory[ (x) ]
    >
    >  Instead of using a function, when you call to ReadMem(), the code is
    > INCLUDED, (no function is called, the "compiler" just substitues the
    > ReadMem( expression ) with memory[ (expression) ] .
    >
    >  I want to avoid function calls to speed up a program by sacrifizing
    > the resulting size ...
    >
    >  Is that possible?


    Python is a slow language and people usually do not even think of such
    micro-optimizations.
     
    Michele Simionato, Nov 12, 2009
    #3
  4. Santiago Romero, 12.11.2009 17:43:
    > Is there a Python version of C's language #define statements?
    >
    > Example:
    >
    > #define ReadMem( (x) ) memory[ (x) ]


    Yes:

    ReadMem = memory.__getitem__

    Stefan
     
    Stefan Behnel, Nov 12, 2009
    #4
  5. On 12 nov, 18:16, Stefan Behnel <> wrote:
    > Santiago Romero, 12.11.2009 17:43:
    >
    > > Is there a Python version of C's language #define statements?

    >
    > > Example:

    >
    > > #define ReadMem( (x) )    memory[ (x) ]

    >
    > Yes:
    >
    >         ReadMem = memory.__getitem__
    >
    > Stefan



    Well, In the above concrete example, that would work, but I was
    talking for multiple code lines, like:


    #define LD_r_n(reg) (reg) = Z80ReadMem(r_PC++)

    #define LD_rr_nn(reg) r_opl = Z80ReadMem(r_PC); r_PC++; \
    r_oph = Z80ReadMem(r_PC); r_PC++; \
    reg = r_op

    #define LOAD_r(dreg, saddreg) (dreg)=Z80ReadMem((saddreg))

    #define LOAD_rr_nn(dreg) r_opl = Z80ReadMem(r_PC); r_PC++; \
    r_oph = Z80ReadMem(r_PC); r_PC++; \
    r_tmpl = Z80ReadMem(r_op); \
    r_tmph = Z80ReadMem((r_op)+1); \
    dreg=r_tmp

    #define STORE_nn_rr(dreg) \
    r_opl = Z80ReadMem(r_PC); r_PC++;\
    r_oph = Z80ReadMem(r_PC); r_PC++; \
    r_tmp = dreg; \
    Z80WriteMem((r_op),r_tmpl, regs); \
    Z80WriteMem((r_op+1),r_tmph, regs)


    But it seems that is not possible :-(
     
    Santiago Romero, Nov 12, 2009
    #5
  6. Santiago Romero, 12.11.2009 18:23:
    > #define LD_r_n(reg) (reg) = Z80ReadMem(r_PC++)
    >
    > #define LD_rr_nn(reg) r_opl = Z80ReadMem(r_PC); r_PC++; \
    > r_oph = Z80ReadMem(r_PC); r_PC++; \
    > reg = r_op
    >
    > #define LOAD_r(dreg, saddreg) (dreg)=Z80ReadMem((saddreg))
    >
    > #define LOAD_rr_nn(dreg) r_opl = Z80ReadMem(r_PC); r_PC++; \
    > r_oph = Z80ReadMem(r_PC); r_PC++; \
    > r_tmpl = Z80ReadMem(r_op); \
    > r_tmph = Z80ReadMem((r_op)+1); \
    > dreg=r_tmp
    >
    > #define STORE_nn_rr(dreg) \
    > r_opl = Z80ReadMem(r_PC); r_PC++;\
    > r_oph = Z80ReadMem(r_PC); r_PC++; \
    > r_tmp = dreg; \
    > Z80WriteMem((r_op),r_tmpl, regs); \
    > Z80WriteMem((r_op+1),r_tmph, regs)
    >
    > But it seems that is not possible :-(


    As Michele said, this is a micro optimisation, likely premature. A function
    is usually good enough for this. If you need more speed (and you seem to be
    targeting direct memory access or something like that), take a look at Cython.

    Stefan
     
    Stefan Behnel, Nov 12, 2009
    #6
  7. Santiago Romero

    TerryP Guest

    If it's such a big hairy deal, just recompile a copy of the C Pre
    Processor to use something other then #, and hook it up to your python
    scripts in a pipe line from a shell wrapper.

    Personally, I'd rather have Lisps lambda or perls sub then Cs
    preprocessor, and even in those cases, Python suffices perfectly
    fine ;).
     
    TerryP, Nov 12, 2009
    #7
  8. Santiago Romero

    greg Guest

    TerryP wrote:
    > If it's such a big hairy deal, just recompile a copy of the C Pre
    > Processor to use something other then #, and hook it up to your python
    > scripts in a pipe line from a shell wrapper.


    Or use a different preprocessor, such as m4, that
    doesn't clash with the # character.

    --
    Greg
     
    greg, Nov 13, 2009
    #8
  9. Santiago Romero wrote:
    > Well, In the above concrete example, that would work, but I was
    > talking for multiple code lines, like:
    >
    >
    > #define LD_r_n(reg) (reg) = Z80ReadMem(r_PC++)
    >
    > #define LD_rr_nn(reg) r_opl = Z80ReadMem(r_PC); r_PC++; \
    > r_oph = Z80ReadMem(r_PC); r_PC++; \
    > reg = r_op
    >
    > #define LOAD_r(dreg, saddreg) (dreg)=Z80ReadMem((saddreg))
    >
    > #define LOAD_rr_nn(dreg) r_opl = Z80ReadMem(r_PC); r_PC++; \
    > r_oph = Z80ReadMem(r_PC); r_PC++; \
    > r_tmpl = Z80ReadMem(r_op); \
    > r_tmph = Z80ReadMem((r_op)+1); \
    > dreg=r_tmp
    >
    > #define STORE_nn_rr(dreg) \
    > r_opl = Z80ReadMem(r_PC); r_PC++;\
    > r_oph = Z80ReadMem(r_PC); r_PC++; \
    > r_tmp = dreg; \
    > Z80WriteMem((r_op),r_tmpl, regs); \
    > Z80WriteMem((r_op+1),r_tmph, regs)


    Someone writing such code and calling it C should be taken behind the barn
    and shot. Which system runs Python but doesn't have a C compiler that knows
    inlining?

    > But it seems that is not possible :-(


    Thank getenv("DEITY") not!

    Uli
     
    Ulrich Eckhardt, Nov 13, 2009
    #9

  10. > > #define STORE_nn_rr(dreg) \
    > >                         r_opl = Z80ReadMem(r_PC); r_PC++;\
    > >                         r_oph = Z80ReadMem(r_PC); r_PC++; \
    > >                         r_tmp = dreg; \
    > >                         Z80WriteMem((r_op),r_tmpl, regs); \
    > >                         Z80WriteMem((r_op+1),r_tmph, regs)

    >
    > Someone writing such code and calling it C should be taken
    > behind the barn and shot.


    That code is mine and maybe you should look the context
    before doing such kind of affirmations.

    In the Intel Pentium and P-II ages, I started to wrote the
    very first Spectrum emulator in C. With that "cpu power", emulators
    had to be written in ASM to be capable to emulate the destination
    machines at 100% full speed in multitasking systems.

    In the emulation world, every CPU cycle you can save is gold,
    and writing the above code as inline code saved lots of CALLS,
    PUSHs/POPs (parameters to stack), and RETs. That allowed ASpectrum
    to run 100% speed on old computers and even to be ported to the
    Sega Dreamcast's 200Mhz CPU.

    Think that Z80ReadMem() can be called up to 6 times in each
    emulated CPU-cycle. Saving 6 CALLs, 6 PUSHes, 6 POPs, and 6 RETs
    in each cycle of the 3.500.000 of Hz **did** make the difference
    that allow Aspectrum to run at 100% speed in ancient machines.

    Obviously, I prefer to write well structured code but I had to
    sacrifize SIZE by SPEED (size as inline code is included in the
    binary executable file).

    Each coding technique has their application environment and using
    inline macros, like loop unrolling or using "register" variables
    fall bellow all the techniques needed to write a fast emulator.

    Now I'm porting the emulator to a scripted language, so I need
    even more previous design ideas before starting to code, so that
    I can achieve (I hope I'll be able to do it with this group's help)
    100% cpu speed in an standard desktop PC.

    > >  But it seems that is not possible :-(

    >
    > Thank getenv("DEITY") not!


    Well, I don't agree with that, "constants" and "macros" wouldn't
    hurt python, when using them in the right situations.

    Thanks a lot anyway for all your help :)
     
    Santiago Romero, Nov 13, 2009
    #10
  11. Santiago Romero

    Bearophile Guest

    Santiago Romero:

    >Obviously, I prefer to write well structured code but I had to sacrifize SIZE by SPEED<


    In C99 you have "inline" (and gcc/gcc-llvm usually inline small
    functions anyway) that helps avoid many macros.


    >  Now I'm porting the emulator to a scripted language, so I need
    > even more previous design ideas before starting to code, so that
    > I can achieve (I hope I'll be able to do it with this group's help)
    > 100% cpu speed in an standard desktop PC.


    The tecniques needed to speed up Python code are very different from
    the ones you use in C. You may need a lot of time to learn Python
    performance tricks. Psyco helps a lot.


    >  Well, I don't agree with that, "constants" and "macros" wouldn't
    > hurt python, when using them in the right situations.


    I miss true constants in Python, but it may be impossible to add them
    to this language, because of how it uses references. In Python you
    rely on convention, writing their names ALL_UPPERCASE.

    Bye,
    bearophile
     
    Bearophile, Nov 13, 2009
    #11
  12. Santiago Romero

    Guest

    Santiago Romero <> wrote:
    >
    >> > #define STORE_nn_rr(dreg) \
    >> >                         r_opl = Z80ReadMem(r_PC); r_PC++;\
    >> >                         r_oph = Z80ReadMem(r_PC); r_PC++; \
    >> >                         r_tmp = dreg; \
    >> >                         Z80WriteMem((r_op),r_tmpl, regs); \
    >> >                         Z80WriteMem((r_op+1),r_tmph, regs)

    >>
    >> Someone writing such code and calling it C should be taken
    >> behind the barn and shot.

    >
    > That code is mine and maybe you should look the context
    > before doing such kind of affirmations.
    >
    > In the Intel Pentium and P-II ages, I started to wrote the
    > very first Spectrum emulator in C. With that "cpu power", emulators
    > had to be written in ASM to be capable to emulate the destination
    > machines at 100% full speed in multitasking systems.
    >


    Hey, I got 100% with ASM ZX Spectrum emulator on a low end 386 :) (I do
    not remember the CPU freqeuncy anymore, maybe 25MHz). First emulator in
    C that appeared on the emu-scene (I guess it was x128) needed 486
    (~80MHz?) to run at realtime. Pentium and Pentium II was A LOT of
    power :)

    ....

    >
    > Now I'm porting the emulator to a scripted language, so I need
    > even more previous design ideas before starting to code, so that
    > I can achieve (I hope I'll be able to do it with this group's help)
    > 100% cpu speed in an standard desktop PC.
    >
    >> >  But it seems that is not possible :-(


    http://perl-spectrum.sourceforge.net/

    It is quite fast IMHO.
    Just remember to use psyco...

    --
    -----------------------------------------------------------
    | Radovan Garabík http://kassiopeia.juls.savba.sk/~garabik/ |
    | __..--^^^--..__ garabik @ kassiopeia.juls.savba.sk |
    -----------------------------------------------------------
    Antivirus alert: file .signature infected by signature virus.
    Hi! I'm a signature virus! Copy me into your signature file to help me spread!
     
    , Nov 13, 2009
    #12
  13. > Hey, I got 100% with ASM ZX Spectrum emulator on a low end 386 :) (I do
    > not remember the CPU freqeuncy anymore, maybe 25MHz).


    Yes, in ASM a simple 25 or 33Mhz 386 computer was able to emulate
    the
    Spectrum. At least, under MSDOS, like did Warajevo, Z80, x128 and
    "Spectrum"
    from Pedro Gimeno.

    > First emulator in C that appeared on the emu-scene (I guess it
    > was x128) needed 486 (~80MHz?) to run at realtime. Pentium and
    > Pentium II was A LOT of power :)


    x128 was not pure C. The first emulator written in pure C was
    Aspectrum,
    although Philip Kendall "finished" FUSE (Free UNIX Spectrum Emulator)
    before my emulator was able to emulate 128K models.

    But currently only FUSE and ASpectrum can be compiled in lost of
    platforms
    (Wii, Dreamcast, PocketPC, NDS...) just by translating the O.S.
    dependent
    functions or if the destination platform supports the Allegro
    library...

    And at least a P1-P2 is needed for that :)

    > http://perl-spectrum.sourceforge.net/
    >
    > It is quite fast IMHO.


    It does not run 100% in my 1.8Ghz centrino computer :-(, but almost.
    At least, is a good start to see that is possible, at least no current
    DualCore computers :)

    Thanks!
     
    Santiago Romero, Nov 13, 2009
    #13
  14. Santiago Romero

    Guest

    Santiago Romero <> wrote:
    >> Hey, I got 100% with ASM ZX Spectrum emulator on a low end 386 :) (I do
    >> not remember the CPU freqeuncy anymore, maybe 25MHz).

    >
    > Yes, in ASM a simple 25 or 33Mhz 386 computer was able to emulate
    > the
    > Spectrum. At least, under MSDOS, like did Warajevo, Z80, x128 and
    > "Spectrum"
    > from Pedro Gimeno.


    And my very own, (sadly, rather little known at the time) 'Nuclear ZX'
    :) It did not use a dispatch table - rather, each Z80 instruction was
    taken as a high byte of the pointer to a 64KB block of 8086 code, low
    byte being zero for unprefixed instructions or a given value for
    prefixed ones. This approach saved one lookup (several cycles) and one
    indirect jump (another several cycles) per instruction. Another
    optimization would be to unroll the return jump from each of the
    emulated instructions and replace it directly with inline
    read-the-next-instruction-and-jump-there code, but I never got around to
    that (would save one 8086 jump per one Z80 instruction :))


    >> http://perl-spectrum.sourceforge.net/
    >>
    >> It is quite fast IMHO.

    >
    > It does not run 100% in my 1.8Ghz centrino computer :-(, but almost.
    > At least, is a good start to see that is possible, at least no current
    > DualCore computers :)


    Python IS slower than perl, especially since you are dealing with
    objects. However, I'd suggest go the cPickle route - have a Z80Cpu
    module, and its C equivalent, cZ80, and use that one if available. This
    way, the emulator will be actually usable everywhere.


    --
    -----------------------------------------------------------
    | Radovan Garabík http://kassiopeia.juls.savba.sk/~garabik/ |
    | __..--^^^--..__ garabik @ kassiopeia.juls.savba.sk |
    -----------------------------------------------------------
    Antivirus alert: file .signature infected by signature virus.
    Hi! I'm a signature virus! Copy me into your signature file to help me spread!
     
    , Nov 15, 2009
    #14
  15. > Python IS slower than perl, especially since you are dealing with
    > objects. However, I'd suggest go the cPickle route - have a Z80Cpu
    > module, and its C equivalent, cZ80, and use that one if available. This
    > way, the emulator will be actually usable everywhere.


    Thanks for the advice but ... my (currently working) emulator is
    already written in C, I don't see the point of calling it from a
    python module. I had 2 options: port the emulator from C+Allegro to C
    +SDL or port it to Python+Pygame+SDL...

    And the fun is trying to write it in pure python with pygame, without
    external C :)

    I'll do a quick test, if I see that I can't achieve 100% speed in my
    other computer (DualCore2 1.82Ghz, the basic-standard-minimum computer
    nowadays), then I'll give up, but at least I want to try it X-D

    Today or tomorrow I'm finishing the pyinliner.py preprocessor X-D.
    I'll paste the results here :)

    Thanks for your answer :)
     
    Santiago Romero, Nov 15, 2009
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. theotyflos
    Replies:
    3
    Views:
    474
    Thomas Matthews
    Feb 19, 2004
  2. Boo Yah
    Replies:
    1
    Views:
    1,499
  3. Replies:
    1
    Views:
    412
    Peter Hansen
    May 27, 2004
  4. robin liu
    Replies:
    3
    Views:
    824
    Robin Liu
    Apr 21, 2006
  5. Brian Takita

    #define _ and #define __

    Brian Takita, Jan 23, 2006, in forum: Ruby
    Replies:
    0
    Views:
    465
    Brian Takita
    Jan 23, 2006
Loading...

Share This Page