kstenerud / Musashi

Motorola 680x0 emulator written in C
412 stars 94 forks source link

useless & CPU intensive operation could be avoided #72

Open jotd666 opened 4 years ago

jotd666 commented 4 years ago

at line 982 of m68kcpu.c there's this loop

        /* Record previous D/A register state (in case of bus error) */
        for (i = 15; i >= 0; i--){
            REG_DA_SAVE[i] = REG_DA[i];
        }

problem is: it's executed at each instruction. Its purpose is to save data & address registers in case of a bus error as the comment states.

But it's not used anywhere else (the da_save data is only written), so I suppose that's a feature for a monitor or something. The fact that at EACH instruction, the CPU copies 32*8 bytes of memory certainly hinders performance.

I suggest to add a configuration macro to enable it only if needed (who has bus errors in a working app anyway ?)

neozeed commented 4 years ago

memcpy(REG_DA_SAVE,REG_DA,sizeof(REG_DA_SAVE));

I think stuff like 3B1 /SUN-2 emulation and other stuff kind of need this? Does the compiler optimize it to a memcpy? is it faster to just make it a memcpy?

I'm just a tourist, beats me. :|

dirkwhoffmann commented 4 years ago

Does the compiler optimize it to a memcpy?

Modern compilers do it the other way round. They usually eliminate calls to memcpy entirely.

Here is an example with gcc (x86):

Bildschirmfoto 2020-08-28 um 09 02 59

Only an architectural change can help here.

Fun fact: gcc uses a MOVEDQA in foo() and a MOVEAPS in bar(). I don't know why. Both instructions should do the same in this context...

jotd666 commented 4 years ago

Hi,

good analysis. I was not debating about the optimized copy vs non-optimized copy. I checked the source code and this copied register part is useless in most cases and should be skipped. It's done every instruction, and on an emulator, everything that is done every instruction should be useful or removed because it wastes a lot of cpu power.

So if it's useful in some cases, maybe add a configuration in the musashi config header file to enable it. In my case, I don't trigger or recover from bus errors so I don't care about backuping the registers

Regards

JFF

Le ven. 28 août 2020 à 09:22, Dirk Hoffmann notifications@github.com a écrit :

Does the compiler optimize it to a memcpy?

Modern compilers do it the other way round. They usually eliminate calls to memcpy entirely.

Here is an example with gcc (x86):

[image: Bildschirmfoto 2020-08-28 um 09 02 59] https://user-images.githubusercontent.com/12561945/91531789-a75da400-e90d-11ea-826e-0fb933414df9.png

Only an architectural change can help here.

Fun fact: gcc uses a MOVEDQA in foo() and a MOVEAPS in bar(). I don't know why. Both instructions should do the same in this context...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kstenerud/Musashi/issues/72#issuecomment-682372058, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD54CEX3UR3L6XZ625TEDS3SC5LKXANCNFSM4LDOD7PA .

kstenerud commented 4 years ago

It was added to support BUSERR based virtual memory and bank switching schemes used in some operating systems and games.

But you are right that in 95% of cases you don't need it, so hiding it behind a config macro is probably a better approach.