managed and unmanaged things related to the Emu
Doomulation said:
And microsoft actually thinks the .NET Framework can beat unmanaged code, as they state? What nonsense! The framework can't produce better code than if written unmanaged it appears!
First of all: English is not my native language so I'm sure there are some sentences that are not right or clumsy combined with some keyboarderrors ^^ it must be horrible for someone who talks english but oversee that fact. Please
I created an account just do comment this post ^^ so be proud :bouncy: .
If you are not interresting in boring explations how the framework works jump to ---MAIN PART
Since I use the .NET framework at work I know nealy everything worth of knowing in the Frameworks 1.0, 1.1, 2.0. You do not have to belive me, but you should think about what I am trying to tell you.
The framework is able to beat unmanaged code but there are some requrements for the statement to be true.
First of all if you think about how JIT-Compilers work JIT compiled code has to be as fast or faster then native code. Just to remember native code is machinecode that was generated once and then published. This machinecode has to be compatible to many systems and therefore can not take advantages of special features on some systems. The JIT compiler (on the system where the application runs) takes an intermediatecode and generates the macinecode just in time optimized for the system where the application is running (there is no need to be compatible to other systems). The machinecode is normaly only generated once (fist use of app or if the system changed) then stored and executed. The time is only lost when starting the app because if the application is running the source is the generated machinecode that should be as fast or faster.
Just to be complete there is no JIT compiler that supports special chipsets (MMX, SSE, SSE2, 3DNOW,..). If they are upraded someday to support that chipsets they generate faster code than now with now additional work for programmers (what are realy an good thing if I think about add MMX support to an programm...brrr)
Now to the .NET framework (and partitially to the JAVA framework).
Garbage colection (GC) only frees memory if there is enougth time (no heavy cpu load) or when it is realy need. (<-should be faster that freeing every time an object is not needed anymore)
So the question is why is the framework slower than native code even when JIT compiling is faster and GC is faster...
The answeres are:
1) GC needs more memory to work efficient. Machines that run frameworks with GC should at least have 1GB Ram better are to. If there is less ram available te GC has to free memory more often and the speed gets down. (Note: .NET GC use Stackcopy the JAVA GC Refereces, both methods have there benefites stackcopy is the saver (and newer) one. Also the .NET GC is working more efficient than the JAVA GC (no wonder if you think that there are 3 years of technology in between (can change after each new Java Version))
2) There are some things that slows the .NET Framwork down that have there reasons in the fact that there are two (incompatible) technologies side by side (Lets call it: Framework with GC / Win32(native)).
And point 2) is the main reason while managed code is "slower" than native code. (Notice: That changed with the Win2003 kernel and will be completly reversed with the VISTA core).
So you can call unmanaged (native) code from within the Framework. Therefor an wrapper is needed for most parts the wrapper can be generated automaticly, only some special wrappers are written by hand (Ex: ManagedDirectX). The automaticly generated wrappers are 10-20 Times slower that the native call of native APIs(all Win32-APIs, unmanaged dlls,...).
As you see time gets lost everytime an Windows API is called. For frequently used APIs (EX: IO Data on the screen) MS included "handwritten" wrappers that are much faster than the automaticaly generated one (x1-x1.5 times slower).
In windows 2003 Kernel .NET runtime runs in kernel mode so no wrappers are needed for API calls (that are in the .NET kernel part). This cals are as fast as there native counterparts. Whats left are the native APIs that are calle from managed code. In VISTA core the only kernelmode thats left is .NET, native code is still suportet but like .NET now in VISTA a wrapper is needet for native code to access the VISTA APIs (10-20 slower than managed calls now)
Ok enouth of the future, it's also not for sure that there will no native kernel APIs VISTA. MS can change that everytime they like better wait for the release to be sure (the betas do not have nativ APIs even when this fact is hidden).
---MAIN PART
Ok now to the main part of this post all other things are just introduction...
I studied the sourcecode of the Emulator and found some parts that slows down the emulator.
But before: gladius you did realy a great work with the emu, so what comes is nothing personal maybe you can get a few hints to make some parts faster.
As described bevore calls of unmanaged APIs are slow ergo -> [DllImport("Kernel32.dll")] <- all calls to funktions of that API are slow
The problem here is that there is not realy an other way, the only "managed" solution that could also work (not tested only thinking about) is Environment.TickCount that should (except for Win98 where one ticks 1 ms) me accurate enouth for the Timer (in WinXP 64 10000 ticks are 1 ms).
The code calles the managed directX APIs. The APIs are .NET 1.1 your code is .NET 2.0. If there is no 1.1 Framework installed the code is running in compatibiliy mode what can cost some speed. (not realy much, I don't know if it's realy noticeable ore not). If .NET 1.1 is installed the 1.1 apis are called for the Interface a small Wrapper 2.0 to 1.0 is made (cost of speed is less than if .NET 1.1 is not installed, not noticeble at all).
The best way would be to use managed DirectX APIs for .NET 2.0 -> Problem they does not exist till DX10 are out.
The memory and cpu classes are not coded for optimal performance I will now give you a few examples of some new features in .NET 2.0 that allow some codeconstructs that could be speed up the classes. Maybe it is usefull.
For fast CPU Register access think about this (works in 1.1 too) (C# code)
The Attributes are located in System.Runtime.InteropServices and can used for struct and classes (im not sure if realy working for classes but using an embeded structure is no problem)
[StructLayout(LayoutKind.Explicit, Size = 2)]
private unsafe struct Registers
{
[FieldOffset(0)]
public ushort AF;
[FieldOffset(1)]
public byte A;
[FieldOffset(0)]
public byte F;
}
For fast access memory its possible to use...(C# code)
(only works in .NET 2.0).
The Attributes are located in System.Runtime.InteropServices and can used for struct and classes (im not sure if realy working for classes but using an embeded structure is no problem)
This code need to be in an unsafe context (note that unsafe is not unmanaged that fact and the differences can be discuss if requested)
[StructLayout(LayoutKind.Explicit, Size = 0xFFFF)]
public unsafe struct Memory
{
[FieldOffset(0)]
public fixed byte complete[0xFFFF];
[FieldOffset(0)]
public fixed sbyte signedComplete[0xFFFF];
}