Archived

This topic is now archived and is closed to further replies.

In need of help understanding dlls & threads

This topic is 5578 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am not new to C++ but i am not a guru either so dont abuse me. Dlls: Is it possible to call functions in the client executable from a dll? I am trying to write a demo 3d engine that uses openGL. What i want to do, is have the rendering code in the executable file, and to have the main loop in the dll. Is this possible? Threads: I sort of know what threads are, but i have a few questions. From my understanding threads are the major part in multitasking and that applications can be multi-threaded. 1. Would it be possible to have one thread running graphics code and another thread running sound code for example? 2. Would this increase game peformance? 3. Can the threads be synchronised, ie so a sound is played and an explosion is drawn at the same time? 4. Can threads even directly communicate with each other? 5. Would this end up making the code to complex? Also another question that i have to ask out of curiosity: Which is quicker for the cpu to calculate? x = 10 * 0.5 or x = 10 / 2 Because i have been told by some that the 1st is, and some by the 2nd is.

Share this post


Link to post
Share on other sites
What i want to do, is have the rendering code in the executable file, and to have the main loop in the dll. Is this possible?
Lookup function pointers. That''s your best bet. Usually, though, the objective is to do things the other way around...

1. Would it be possible to have one thread running graphics code and another thread running sound code for example?
Yes.

2. Would this increase game peformance?
Not necessarily.

3. Can the threads be synchronised, ie so a sound is played and an explosion is drawn at the same time?
Yes, but why not delegate such issues to the graphics and audio subsystems which work on their own dedicated processors (GPU, sound card)?

4. Can threads even directly communicate with each other?
Sure.

5. Would this end up making the code to complex?
Not necessarily. It''s all about how you structure it.

quote:

Also another question that i have to ask out of curiosity:
Which is quicker for the cpu to calculate?

x = 10 * 0.5
or
x = 10 / 2

It depends. The first is a floating point multiplication while the second is an integer division. Division is slow, but floating point operations are slower than integer ops - or at least used to be. The final conclusion is that it doesn''t matter, because those operations are so atomic that they have little impact on overall performance. Premature optimization is the root of much evil, so code, debug, profile and then optimize.

Share this post


Link to post
Share on other sites
From what I know, the mathematical operators are stored in a linked list, sort of like a tree, and data is inputed into the tree and carried about the root nodes until it comes out...

I think, THINK, that * comes before /, so * would be faster, but that''s only from my biased knowledge.

~ Jesse

The gl2D Project | Free programming books

Share this post


Link to post
Share on other sites
quote:

Also another question that i have to ask out of curiosity:
Which is quicker for the cpu to calculate?

x = 10 * 0.5
or
x = 10 / 2

Like Oluseyi said, it depends on the type of x, but any good compiler should choose the best form out of those two, IMO. If you do keep the constants, the result (5) will almost certainly be evaluated at compile-time, so it doesn''t matter. If what you meant is,

x = y * 0.5
or
x = y / 2

A smart compiler should optimize both as x = y >> 2 anyway (if x is an integer)

Cédric

Share this post


Link to post
Share on other sites
If you care about precision and/or you''re doing scientific
or numeric programming, the choice is clear. Use multiplication
when you''re dealing with floating point numbers.

In other words:


// Don''t do this!
double x = 1.0;
x /= 2.0;

// Do this instead
double x = 1.0;
x *= 0.5;




Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
When thinking about threads, consider that main/WinMain are also threads. It''s obvious, but it goes unsaid. What that means is that you already have experience dealing with threads at that level. A thread merely describes a path of execution within a process. It''s when you launch additional threads that issues arise. Specifically, it''s when more than one thread has an "interest" in a particular piece of data that issues arise. That is where synchronization objects come into play - semaphores, mutexes, critical sections and the like. They act like traffic cops making certain that one thread has the current right of way. Multithreading is cool - but it''s just another tool. That makes the question is it the right tool for the job? Unfortunately, there are no hard and fast answers to that question.

Share this post


Link to post
Share on other sites
Poeple often think that multithreading == faster.

That''s ... wrong. Multithreading is just a very easy way to do several things "at the same time" with different priority without having to code a process controler.

For instance, having a low priority thread to load the next map while you are playing. This will actually slow down the game, but not enough to be noticeable. The map will load very slowly. The result, you are sacrificing little percentage of overall performence to load the maps so that there is no APPARENT loading time.

The only time multithreading will actually boost performence is when you loose tremendous time waiting after resources and locks. You can use this time for usefull things in another thread.

______________________________
Oooh, you found the horadric cube!

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
Division is slow, but floating point operations are slower than integer ops - or at least used to be.


hm.. not really true anymore.. we''ve made a little realtime rastericer, and to get it fast, we used fixedpoint.. then we replaced the typedefs with floats, and still did the whole fixedpoint math (alot of bitshifts wich then got floatdivisions! the most terrible thing in floats:D), the result was a speed drop of about 1fps.. plugging out the float divisions (wich are known to be quite slow), and we where much faster..

integers are by no means that fast, about every major float instruction takes 1 cycle if the cpu can optimize it well.. (else about 3 or so..)

the trig funcs and those are something different.. division is slow as well, but it is on integers, too..

those results are from benches on an amd, and on a p3..

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Ok, it''s like this. If you want to see threads easily then see them as multiple instances of the WinMain() or main() function. It is a thread running until you tell it to stop. (If you are using old C functions it would be with _beginthread() and _endthread())
So, it is just a clean and easy way to do this simultaneously without having to time each and every one from one main process. Each process can communicate with every other process and you can basically do whatever you want with them.

Now DLLs are a little different. A dynamic link library is very similar to a .LIB file, meaning it contains sourcecode that is not stored in .cpp or .c files, but instead compiled into a dll and used at run-time. Windows registers every DLL-file and then if a program needs it, it uses it if:
1. The DLL is in the .exe file''s directory
2. The DLL is in Window/System
3. The DLL is in any other folder specified with PATH at startup.

Those kind of optimizations you are talking about are really ridicilous to do right now. If your game later runs slow, then you can start optimizing big things, floating point multiplication or division comes pretty much in the end when you can improve the way you render, blit and calculate collision.

Share this post


Link to post
Share on other sites
quote:
Original post by Exorcist
x = 10 * 0.5
or
x = 10 / 2


Just write a small test programm, performing 100000 or so multiplications and divisions, and measuring the time. I''d do it, but I''m just performing a dev-c++ auto-update.


_________________________
"Reality is merely an illusion, albeit a very persistent one." (Albert Einstein)
My Homepage

Share this post


Link to post
Share on other sites
quote:
Original post by Coincoin
The only time multithreading will actually boost performence is when you loose tremendous time waiting after resources and locks. You can use this time for usefull things in another thread.


If you run a multithreaded prog on a multi-processor system both processors will run threads simultaneously, and thus speed up the apps execution. The biggest advantages of multithreading is simplifying design and creating a more responsive app.

"Simplifying design"??

I know that sounds odd because of all the thread debugging horror stories. But humans naturally think of solutions in multithreaded ways. After years in comp.sci. classes or reading books or online tutorials, we've been conformed to think of single threaded solutions as best. If you arm yourself with proper knowledge of the quirks and pitfalls of mt programming, writting a mt prog can be quicker (development time, not necessarily run time) and more bug free than its ut counter part.

The "creating more responsive app" part was already mentioned. Have one thread load resources during game play. Or have one thread control the user interface and mouse movement and another thread run the calculations. This way, the user interface will alway be snappy and responsive and won't get bogged down waiting for the calculations to take a break to process user input.

[edited by - spiffgq on September 1, 2002 4:04:58 PM]

Share this post


Link to post
Share on other sites
Oh right, just to add, an easy look into multithreaded programming can be found in the Windows 9x/2000 SDK (NT differs some from its 9x counterpart since it is built on the old OS/2 kernel). There you can see what it does and how it does it. It''s not simple to master, but quite easy to start dabbling and fucking up, heh.

http://www.msdn.microsoft.com <--- good place to start, because personally I find windows multithreading easier than any *nix system.

Share this post


Link to post
Share on other sites
quote:
Original post by cedricl

x = y * 0.5
or
x = y / 2

A smart compiler should optimize both as x = y >> 2 anyway (if x is an integer)

Cédric


A small correction, it should optimize as x = y >> 1( 2 to the powere of 1 ). Shifting works with powers of 2...



"DaHjajmajQa''jajHeghmeH!"

Cyberdrek
danielc@iquebec.com
Founder
Laval Linux

/(bb|[^b]{2})/ that is the Question -- ThinkGeek.com
Hash Bang Slash bin Slash Bash -- #!/bin/bash

Share this post


Link to post
Share on other sites

void function1()
{
//first function

}

void function2()
{
//second function
}

int main(int argc, char* argv[])
{

char str;
DWORD start,end,total;
DWORD time1,time2,diff;
start=end=total=time1=time2=diff=0;

for(int j=0;j<5;j++)
{

start=timeGetTime();
//thing to test here
printf("Function type 1\n");
for(int i=0;i function1();
end=timeGetTime();
total=end-start;
time1=total;
printf(_ultoa( total, &str, 10));
start=end=total=0;
start=timeGetTime();
printf("\nFunction type 2\n");
for(i=0;i function2();
//end thing to test
end=timeGetTime();
total=end-start;
time2=total;
printf(_ultoa( total, &str, 10));
printf("\n\n");
if(time1<=time2)
{
diff=time2-time1;
printf("\nfunction1 is faster\n");
}
else
{
diff=time1-time2;
printf("\nfunction2 is faster\n");
}
printf("Time Difference\n");
printf(_ultoa( diff, &str, 10));
printf("\n\n");
}
return 0;
}


plug in to function1 and function2 the two different forms your testing, and it will tell you the time differenct. the more loops you use, the more of a difference you will see, which is generally better. it''s a simple win32 console app, took about 5 minutes

___________________
-Nicholas Anton
-www.geocities.com/nickanton7/

REFUSE TO BUY WINDOWS XP! STAY WITH 98se!! MICROSOFT CUTTING SUPPORT FOR OLDER PROGRAMS IS A VERY BAD THING.

Share this post


Link to post
Share on other sites
When thinking about using multithreading, remember this - the purpose of multithreading is to increase responsiveness, not performance.

eg. uses I''ve seen in gaming...
1) if you are loading things from the HDD - the harddisk is slow compared to the processor and the processor has to stop and wait for the diskdrive to do its stuff
2) if you are polling sockets once per game cycle for input, and the packets are arriving fast enough that it might overflow the buffer (and you''ll get dropped packets)... what you really need in this case is a separate thread dedicated to reading the incoming packets out of the socket buffer and storing them somewhere until the main game loop gets around to processing them.
3) for loading multimedia in the background - sound, music, textures, geometry, video

I''ve also seen people put rendering or AI in a separate thread - this is not something I would advise trying until you have some experience writing multithreaded applications and already have a few games under your belt. There are a lot of tradeoffs in this approach - mostly that your code gets a lot more complex, harder to debug, and you may or may not see a performance increase. People have been doing games for a long time without multithreading for AI/rendering, there are lots of other things I''d rather waste my time trying rather than trying to debug multithreaded code which is like 2 or 3 times harder to debug/write than unthreaded code.

Share this post


Link to post
Share on other sites
Original post by Raptor85


  
void function1()
{
//first function


}

void function2()
{
//second function

}

int main(int argc, char* argv[])
{

char str;
DWORD start,end,total;
DWORD time1,time2,diff;
start=end=total=time1=time2=diff=0;

for(int j=0;j<5;j++)
{

start=timeGetTime();
//thing to test here

printf("Function type 1\n");
for(int i=0;i<NUMBER_OF_LOOPS;i++)
function1();
end=timeGetTime();
total=end-start;
time1=total;
printf(_ultoa( total, &str, 10));
start=end=total=0;
start=timeGetTime();
printf("\nFunction type 2\n");
for(i=0;i<NUMBER_OF_LOOPS;i++)
function2();
//end thing to test

end=timeGetTime();
total=end-start;
time2=total;
printf(_ultoa( total, &str, 10));
printf("\n\n");
if(time1<=time2)
{
diff=time2-time1;
printf("\nfunction1 is faster\n");
}
else
{
diff=time1-time2;
printf("\nfunction2 is faster\n");
}
printf("Time Difference\n");
printf(_ultoa( diff, &str, 10));
printf("\n\n");
}
return 0;
}


When posting a lot of code like this, use "source" instead of "code" so that the less-than symbols don''t get misinterpretted as html tags. "code" only preserves spacing. Another tip for using "source" - insert an extra newline after the include directives, that will prevent them from getting bunched up on the same line.

Share this post


Link to post
Share on other sites
I believe the only point why AI is made in separate threads is just as you mentioned it, because of CPU waitstates. Meaning the AI can still think raptly even if the CPU waits for the GFX card to texture the wireframes just being produced.
But yes, it is more complicated, although you get lesser AI waitstates.

Valkyrias: Tears of Valkyries