View previous topic :: View next topic |
Author |
Message |
bobef
Joined: 05 Jun 2005 Posts: 269
|
Posted: Tue Aug 23, 2005 12:38 pm Post subject: Performance |
|
|
Just wondered... How long will it take to link all these libraries at run time? I mean all of them. |
|
Back to top |
|
|
JJR
Joined: 22 Feb 2004 Posts: 1104
|
Posted: Tue Aug 23, 2005 2:13 pm Post subject: |
|
|
Good question. I've never tried loading up SDL, OpenGL, GLFW, etc all at once. But, in my experience, generally the dynamic linking is extremely fast. I would imagine that it's easily less than 1 second to load all libraries. I've done a similar process with DUI and GTK on linux and windows. There are many, many symbols to load in GTK, much more, I believe, than in Derelict. Even there I don't notice the delay on either platform.
I guess the only sure way to know, though, is to time it. Get the time before and after the Derelict***_Load() functions.
-JJR |
|
Back to top |
|
|
h3r3tic
Joined: 30 Mar 2004 Posts: 261 Location: Torun, Poland
|
Posted: Thu Aug 25, 2005 8:04 am Post subject: |
|
|
Loading OpenGL with all 1.5 extensions, SDL, DevIL and ODE takes virtually no time on my Athlon2000+ |
|
Back to top |
|
|
404FileNotFound
Joined: 20 Aug 2005 Posts: 18
|
Posted: Fri Aug 26, 2005 3:24 pm Post subject: |
|
|
I have a totally unrelated question about performance. I have recently tried to reimplement one of my java thingies in D. It's a fairly simple proggie, it loads one texture and draws bits of it on the screen in 2d (a map for the online game continuum). in java it uses lwjgl for rendering the opengl and in D it uses derelictSDL for it but other than that the code is about the same. Somehow in java I get about 120 fps while in D it gets no higher than 43 at the same res. I also noticed that my processor usage is pretty low with the D prog (no higher than 8?), so is SDL to blame for the performance dent? Does anyone else have any performance problems with D/DerelictSDL/opengl as compared to other opengl bindings? Or maybe Im just doing something wrong? |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Sat Aug 27, 2005 3:24 am Post subject: |
|
|
404FileNotFound wrote: | I have a totally unrelated question about performance. I have recently tried to reimplement one of my java thingies in D. It's a fairly simple proggie, it loads one texture and draws bits of it on the screen in 2d (a map for the online game continuum). in java it uses lwjgl for rendering the opengl and in D it uses derelictSDL for it but other than that the code is about the same. Somehow in java I get about 120 fps while in D it gets no higher than 43 at the same res. I also noticed that my processor usage is pretty low with the D prog (no higher than 8?), so is SDL to blame for the performance dent? Does anyone else have any performance problems with D/DerelictSDL/opengl as compared to other opengl bindings? Or maybe Im just doing something wrong? |
Without seeing any code all anyone can do is guess. You don't mention DerelictGL, but I assume you are using it since DerelictSDL is not an opengl binding. And in that case, you surely shouldn't be seeing such a drastic difference. Please post your code so I can see what's going on.
And I hate to be pedantic, but unrelated posts usually call for a new thread! |
|
Back to top |
|
|
404FileNotFound
Joined: 20 Aug 2005 Posts: 18
|
Posted: Sat Aug 27, 2005 4:22 pm Post subject: |
|
|
Yea it uses derelictGL. My source is a bit too big to post here completely Im afraid. All in all it's about 1000 lines already. I'll show some of the more interesting sections:
Here's the main part of the rendering code (incomplete, so some var defs could be missing)
Code: |
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(-(x?16), -(y?16), 0);
tileset.startSession();
int tile;
for (int j=ulY; j<lrY-1; j++) {
for (int i=ulX; i<lrX; i++) {
tile = cast(int)level[i][j];
if (tile > 0 && tile < 190) {
tileset.sessionDraw( tile-1, (i-ulX)<<4, (j-ulY)<<4 );
}
}
}
tileset.endSession();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
SDL_GL_SwapBuffers();
|
Where those 3 tileset functions are:
Code: |
void startSession() {
glBindTexture(GL_TEXTURE_2D, textureID);
glBegin(GL_QUADS);
}
void sessionDraw(int tileNum, float x=0, float y=0) {
// top left
glTexCoord2f(tileX[tileNum], tileY[tileNum]);
glVertex2f(x, y);
// top right
glTexCoord2f(tileBottomX[tileNum], tileY[tileNum]);
glVertex2f(x + tileWidth[tileNum], y);
// bottom right
glTexCoord2f(tileBottomX[tileNum], tileBottomY[tileNum]);
glVertex2f(x + tileWidth[tileNum], y + tileHeight[tileNum]);
// bottom left
glTexCoord2f(tileX[tileNum], tileBottomY[tileNum]);
glVertex2f(x, y + tileHeight[tileNum]);
}
void endSession() {
glEnd();
}
|
Hope you can see anything I'm doing wrong here |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Sat Aug 27, 2005 4:31 pm Post subject: |
|
|
Nothing jumps out at me. But the problem might not even be in the rendering code. Compile the program with -profile, then run it. You should see a file called 'trace.log' or some such in the working directory. Paste that here and we'll go from there. |
|
Back to top |
|
|
404FileNotFound
Joined: 20 Aug 2005 Posts: 18
|
Posted: Sun Aug 28, 2005 2:09 am Post subject: |
|
|
Here's the list on the lower part of that file (since that's the only part that looked readable to me).
Code: |
======== Timer Is 1193182 Ticks/Sec, Times are in Microsecs ========
Num Tree Func Per
Calls Time Time Call
1 3889223 3889133 3889133 _D3gfx3gfx7initSDLFZv
1 3210312 3210312 3210312 _D3gfx3gfx7exitSDLFZv
404 3136366 2323095 5750 _D3lvl11subspacemap11SubspaceMap4drawFiiZv
416120 795209 795209 1 _D3gfx7texture12TextureGroup11sessionDrawFiffZv
404 3798566 662199 1639 _D3gfx3gfx4drawFZv
1 11519834 418426 418426 __Dmain
1 103182 102996 102996 _D3lvl11subspacemap11SubspaceMap10parseLevelFAaZv
3 50258 50258 16752 _D8derelict4util6loader24Platform_UnloadSharedLibFC8derelict4util6loader9SharedLibZv
1 4066653 48489 48489 _D3gfx3gfx7initGFXFZv
1 23848 23279 23279 _D3gfx13textureloader11loadTextureFAaPiPiZk
404 15103 15103 37 _D3gfx7texture12TextureGroup12startSessionFZv
3 13808 13802 4600 _D8derelict4util6loader22Platform_LoadSharedLibFAaZC8derelict4util6loader9SharedLib
559 5161 3275 5 _D8derelict4util6loader16Derelict_GetProcFC8derelict4util6loader9SharedLibAaZPv
404 2957 2957 7 _D3gfx7texture12TextureGroup10endSessionFZv
10 1987 1987 198 _D4game9exception12debugMessageFAaZv
348 5218 1958 5 _D8derelict6opengl8internal7getProcFAaZPv
559 1886 1886 3 _D8derelict4util6loader16Platform_GetProcFC8derelict4util6loader9SharedLibAaZPv
1 6508 1535 1535 _D8derelict6opengl7glfuncs6loadGLFZv
186 2722 1041 5 _D8derelict3sdl3sdl7getProcFAaZPv
1 3687 965 965 _D8derelict3sdl3sdl4loadFZv
1 128633 954 954 _D3lvl11subspacemap11SubspaceMap5_ctorFAaZC3lvl11subspacemap11SubspaceMap
190 565 565 2 _D3gfx7texture12TextureGroup7addTileFiiiiZi
25 359 138 5 _D8derelict3sdl5image7getProcFAaZPv
1 478 119 119 _D8derelict3sdl5image4loadFZv
1 307 97 97 _D3gfx3gfx10initOpenGLFZv
1 23930 77 77 _D3gfx7texture12TextureGroup5_ctorFAaZC3gfx7texture12TextureGroup
1 321 76 76 _D8derelict6opengl3wgl14loadPlatformGLFZv
1 25820 40 40 _D4game4main13loadLibrariesFZv
3 50279 20 6 _D8derelict4util6loader24Derelict_UnloadSharedLibFC8derelict4util6loader9SharedLibZv
3 13826 17 5 _D8derelict4util6loader22Derelict_LoadSharedLibFAaZC8derelict4util6loader9SharedLib
1 7722 16 16 _D8derelict3sdl3sdl16DerelictSDL_LoadFAaZv
1 11832 15 15 _D8derelict6opengl2gl15DerelictGL_LoadFAaZv
1 5317 10 10 _D8derelict3sdl5image21DerelictSDLImage_LoadFAaZv
1 3210322 9 9 _D3gfx3gfx7exitGFXFZv
1 49868 8 8 _D8derelict6opengl8internal14internalUnloadFZv
1 11838 6 6 _D8derelict6opengl2gl15DerelictGL_LoadFZv
1 290 6 6 _D8derelict3sdl5image23DerelictSDLImage_UnloadFZv
1 4985 6 6 _D8derelict6opengl8internal12internalLoadFAaZv
1 49880 5 5 _D8derelict6opengl2gl11_staticDtorFZv
1 49885 5 5 __moddtor_8derelict6opengl2gl
1 49874 5 5 _D8derelict6opengl2gl17DerelictGL_UnloadFZv
1 151 5 5 __moddtor_8derelict3sdl3sdl
1 296 5 5 _D8derelict3sdl5image11_staticDtorFZv
1 5323 5 5 _D8derelict3sdl5image21DerelictSDLImage_LoadFZv
1 145 5 5 _D8derelict3sdl3sdl11_staticDtorFZv
1 7728 5 5 _D8derelict3sdl3sdl16DerelictSDL_LoadFZv
3 5 5 1 _D8derelict4util6loader9SharedLib5_ctorFPvAaZC8derelict4util6loader9SharedLib
1 301 5 5 __moddtor_8derelict3sdl5image
1 139 5 5 _D8derelict3sdl3sdl18DerelictSDL_UnloadFZv
2 3 3 1 _D3gfx13textureloader8get2foldFiZi
2 3 3 1 _D3gfx7texture8get2foldFiZi
1 0 0 0 _D3gfx3gfx10exitOpenGLFZv
|
I went over my code again but I really can't spot any expensive operations in the render loop. My java version does a lot more than the D version (also does some collision detection and physics), while getting higher framerates, it just makes no sense to me |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Sun Aug 28, 2005 4:02 am Post subject: |
|
|
Is the code for SubspaceMap.draw the same as the tileset drawing code you posted earlier?
Next thing I can think of is to compile without -debug or -g, and with -release and -O. See if that makes any difference.
I haven't done any LWJGL/Derelict comparisons, but I just don't see how there can be any sort of difference at that level in LWJGLs favor. In D, bindings to C API calls are direct. In Java, they have to go through the JNI as a proxy. On top of that, many of the LWJGL calls do validation on the direct buffers (FloatBuffers and such) that you pass to the functions. So I just can't see the difference being at the binding level. And it surely wouldn't be SDL as that is only used to create the Window and OpenGL context.
Other things to check for - are you setting up the same pixel format? You can verify this through the following OpenGL calls:
int x = glGetInteger([constant]);
where constant is one of GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, or GL_ALPHA_BITS. You can also check for depth, stencil, and accumulation buffer R, G & B bits. In LWJGL, use org.lwjgl.opengl.Util.glGetInteger.
Make sure you are passing SDL_HWSURFACE as a flag to SDL_SetVideoMode. I don't know if it's possible to get a software OpenGL implementation without that flag as I haven't dug around the SDL source to see the pixel format selection code, but I always use it to be safe.
Are you turning off vsync in LWJGL? And if not (and assuming you are running fullscreen), call org.lwjgl.opengl.Display.getDisplayMode after you have created the window to see what the refresh rate of the display mode is (or check the refresh rate of the DisplayMode object you pass to Display.create). I don't know of any way to check this through the SDL API, so if you are on Windows then you can get that info through the Win32 API. If you don't want to go that route, then when iterating the available DisplayModes in LWJGL select one with a refresh rate of 60. Pass that to Display.create and see what happens.
If none of this pans out, I don't know what to tell you. If you don't mind sharing your source, I would happily compile both versions on my system to see what comes up and try to help troubleshoot. I have the lastest LWJGL (0.9 and Eclipse 3.1, Netbeans 4.1, and Ant - so I will be able to build any project/build files for those environments (assuming you have no other dependencies). I'm hoping it's something simple like a vsync issue though. |
|
Back to top |
|
|
404FileNotFound
Joined: 20 Aug 2005 Posts: 18
|
Posted: Sun Aug 28, 2005 7:06 am Post subject: |
|
|
I sent the info in a PM to you |
|
Back to top |
|
|
JJR
Joined: 22 Feb 2004 Posts: 1104
|
Posted: Sun Aug 28, 2005 12:09 pm Post subject: |
|
|
Another thing to consider:
This may seem strange, but I experienced a severe degradation in performance while working with glfw on win32 awhile ago.
I was working on getting a dynamic glfw binding working with D (pre-derelict, I think). I had compiled several versions of the C glfw.dll with different compilers: openwatcom and dmc specifically. I also was testing the bindings with the pre-compiled glfw.dll file provided from the glfw project.
Strangely, I found the C version running full speed, but the D version ran approximately half the speed (fps; using opengl in both cases). I believe that this problem arose while using using the included glfw.dll and dmc compiled versions of the dll. I then tried compiling glfw.dll with openwatcom. After trying that version with d opengl project, I found that the demo now ran at the same speed as the C original. I don't know why this was so, but it seemed the performance degradation was due to which C compiler was being used for the dll. But the performance problem only showed up when I using it from d. I'm not sure if I tried compiling the dll with mingw gcc.
That said, perhaps the SDL dll in some way is an issue here? I know that doesn't make much sense since opengl uses it's own dll... but you never know. I couldn't make sense of my problem either.
-JJR |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Sun Aug 28, 2005 10:51 pm Post subject: |
|
|
It looks like a vsync issue. When I first ran the Java version, I was getting 500+ frames per second, and the D version was consistently giving me 59.xxxx. So I searched the Java files for vsync, and sure enough I found this on line 178 of Game.java:
// Display.setVSyncEnabled(true);
Uncommenting that line caused the framerate to drop to 75 fps. Although you were requesting 85hz refresh rate, the display mode that was being set was 75hz. And just to be sure, I changed the Display.setDisplatMode call to request 60hz and the framerate dropped to 60.
Next, I visited the D code. Either SDL is consistently setting a display mode with a 60hz refresh rate, or something is horribly wrong. So to verify this I added the following to the top of gfx.d:
Code: |
pragma(lib, "gdi32.lib");
import std.c.windows.windows;
const int VREFRESH = 116; // from wingdi..h
|
Then at the bottom of the initSDL function:
Code: |
HDC dc = GetDC(null);
debugMessage("Refresh Rate: " ~ toString(GetDeviceCaps(dc,VREFRESH)));
ReleaseDC(null, dc);
|
The result printed was 60. This also indicates that the OpenGL context is being created with vsync by default. So, to verify, I did the following:
Code: |
import derelict.opengl.wgl; // added with other derelict imports
// added this after the std.c.windows.windows import
extern(Windows) typedef BOOL function(int) pfwglSwapIntervalEXT;
pfwglSwapIntervalEXT wglSwapIntervalEXT;
// and added this at the end of initSDL
wglSwapIntervalEXT = cast(pfwglSwapIntervalEXT)wglGetProcAddress("wglSwapIntervalEXT");
if(wglSwapIntervalEXT !is null)
wglSwapIntervalEXT(0);
else
debugMessage("No wglSwapIntervalEXT");
|
This resulted in the D code running at ~500 FPS just as the Java code does with setVSyncEnabled commented out.
So the root of your problem appers to be that LWJGL is creating an OpenGL context with vsync disabled, while SDL is creating one with vsync enabled. Try these changes on your system and see what turns up.
I notice the frame rates I'm getting are quite higher than what you saw, so here are my specs for comparison:
AMD 2600 (~1.9GHZ)
Geforce 6600 GT 128MB
2GB RAM
Windows XP SP2 |
|
Back to top |
|
|
JJR
Joined: 22 Feb 2004 Posts: 1104
|
Posted: Sun Aug 28, 2005 11:12 pm Post subject: |
|
|
Wow! Good catch, Mike!
Now that you mention it, I guess we should be suspicious about vsync whenever we see a frame rate consistantly hover around 59.xxx.
-JJR |
|
Back to top |
|
|
404FileNotFound
Joined: 20 Aug 2005 Posts: 18
|
Posted: Mon Aug 29, 2005 4:19 am Post subject: |
|
|
Wow thanks for doing all that, however the weird thing is that I was testing with a refresh rate of 85 Hz, while getting somewhere around 40 fps. Now even if the refresh rate was somehow not 85 Hz, my monitor doesn't go lower than 60 for sure. I can't test on the same machine as previously anymore (Im no longer at my parents place) but I'll see what my laptop does with it.
My previous testing machine was a P3 800 MHz, with 768 MB ram and a Geforce 4 Ti4200 64 MB, so yea your machine should be a bit faster than mine
Anyway thanks a bunch I'll try your changes later and let you know what happend |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Mon Aug 29, 2005 2:57 pm Post subject: |
|
|
404FileNotFound wrote: | Wow thanks for doing all that, however the weird thing is that I was testing with a refresh rate of 85 Hz, while getting somewhere around 40 fps. Now even if the refresh rate was somehow not 85 Hz, my monitor doesn't go lower than 60 for sure. |
No monitor goes below 60hz! I think what was happening on the other machine is that SDL was giving you a 60hz refresh rate with vsync enabled and you were just capping out at 43 fps, while Java was giving you 85hz with no vsync and you were capping out at 120 fps.
Quote: | I can't test on the same machine as previously anymore (Im no longer at my parents place) but I'll see what my laptop does with it. |
If you can get back to your parents' machine and test with the changes to the D code above, I think you'll find it caps out around 120 fps also.
Just because vsync is enabled doesn't mean you will always cap out at the refresh rate. If you aren't ready to draw on the current vertical retrace, then you'll be waiting for the next. And that means the framerate numbers can actually take a large hit. On my machine, something is ready to be displayed with each vertical retrace, thereby giving me an FPS value equal to the refresh rate. On your parents' machine, that is not the case. Every few frames you are missing a vertical retrace and having to wait for the next one, thus the 43 fps. If you were missing it every other frame you'd be seeing around 30 fps. So what you're seeing isn't uncommon at all on older machines. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|