I’ve implemented the Bresenham Line algorithm in RLP using a PutPixel implemented as assembler.
Then I’ve made a demo in managed code that moves some lines on the screen.
When I run the demo with the RLP Line function, the code is more then 10 times slower then when I draw the lines on a Bitmap and then Flush to the screen.
Just curious but I hardly know anything about RLP…
if replace the ASM part by NOP (s)
of course you are not going so see anything on the screen,
but if you measure, is this “nothing” faster than managed ?
To figure out if the the slow comes from the putpixel or something else ?
I don’t know ARM assembler, but I use to meet similar problems on programming direct VESA video access to PCs.
I remember beeing disapointed writting a graphic library for PC, and it was very slow, however everything was written in assembler. Accessing video ram pixel per pixel was very slow, but if I was doing it in memory, I could dump / copy all the memory to video ram with a 4 lines assembler like
"rep stosw" etc and the speed was fine.
@ Nicolas: Thanks for your suggestion. When I think about it, the method you describe is the way it works when using the bitmap flush. So it is worth to give it a try.
[quote]Amazing Double as fast as the bitmap method.
Conclusion: Invoking methods from RLP has a huge overhead. GHI, how can this be finetuned? [/quote]
Did you try a single invoke with GeneralArray?
I’m curious how that compares to your best time without generalarray - 488ms.
Have you tried taking the word “inline” out of the function declaration? The function is a bit big for inlining and may be hurting you. You also can’t really inline functions with managed code (not manually anyway, the JITter does it) so that may be adding some overhead there.
DateTime start, end;
int e = 0;
int[] intArray = new int[100];
byte[] byteArray = new byte[100];
start = DateTime.Now;
DoNothing.Invoke();
end = DateTime.Now;
Debug.Print("Invoke() in " + (end - start).Ticks / 10 + " micro seconds");
start = DateTime.Now;
DoNothing.Invoke(e);
end = DateTime.Now;
Debug.Print("Invoke(int) in " + (end - start).Ticks / 10 + " micro seconds");
start = DateTime.Now;
DoNothing.InvokeEx(intArray);
end = DateTime.Now;
Debug.Print("InvokeEx(int[]) in " + (end - start).Ticks / 10 + " micro seconds");
start = DateTime.Now;
DoNothing.InvokeEx(intArray, byteArray);
end = DateTime.Now;
Debug.Print("InvokeEx(int[], byte[]) in " + (end - start).Ticks / 10 + " micro seconds");
start = DateTime.Now;
DoNothing.Invoke(byteArray, byteArray);
end = DateTime.Now;
Debug.Print("Invoke(byte[], byte[]) in " + (end - start).Ticks / 10 + " micro seconds");
We get these results:
So passing no arguments is fast.
general array is the next best option.
We can optimize RLP in future but this requires major changes on invoking and passing arguments…
Could you try the same test, but wrap the function calls in an unsafe {} block? You will need to go into the project preferences to allow unsafe code to compile and run it.