Jump to content
  • Advertisement

Archived

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

Jx

Choosing which lib automatically at runtime

This topic is 5993 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

Ok, so i''ve got my nice shiny vector and maths libraries, optimized for SSE and 3DNow!. All I want to be able to do now is say: Matrix3 tempMatrix = new Matrix3; and have it automatically return SSE or 3DNow! version. I would like not have to have if''s or cases to do this... Anyone got any solutions? I''ve thought of ways, but i don''t like them very much Hopefully someone can help....

Share this post


Link to post
Share on other sites
Advertisement
Well, you can use function pointers in C, or an abstract base class and virtual functions in C++. Both may incur considerable overhead if you''re looking to maximize performance.

You need to abstract at a higher level in the code, and construct two (or more) different functions, each using inlined MMx/SSE/3DNow code.

So instead of deciding which matrix multiplication you use, you decide which physics engine you''re going to use.

You can then either use macros and conditional compilation, or templates to produce the various flavors of the physics engine.

Share this post


Link to post
Share on other sites
You could just use different executables, using #ifdefs in your matrix functions to seperate the MMX, SSE, and 3DNow code. Then you compile it with the different defines, into GameMMX.exe, GameSSE.exe, and Game3DNow.exe, or whatever. Since no one's processor is going to change at run time, you can let the user choose which to download instead of cramming all three into one ZIP archive.

~CGameProgrammer( );



Edited by - CGameProgrammer on February 18, 2002 11:08:47 PM

Share this post


Link to post
Share on other sites
use the magic of polymorphism. though you will have to screw around with the new operator so that it creates the correct class, or call a special CreateMatrix() function so that you dont have to deal with overriding new. unfortunatly there is NO way to do this without some sort of conditional (if/switch) code somewhere.

Share this post


Link to post
Share on other sites

Hmm... runtime... dynamic... switching... Wait a minute!

Hey, isn''t that what DLL or shared libraries are for?!?

That''s right.

Make two DLL''s, one for SSE and one for 3DNow.

The DLL''s both "export" Matrix3 but are implemented
accordingly.

Call them MatrixSSE.dll and Matrix3DNow.dll.

Then your main program load the "Matrix.dll" which contains
the Matrix3 class. Simply copy the version of the DLL
you want to "Matrix.dll" and VOILA.

Alternatively, you can have a configuration that loads
the specific DLL explicitly.

But you get the idea.


Premature optimizations can only slow down your project even more.

Share this post


Link to post
Share on other sites
Thanks for all the suggestions guys. Some i''d already thought of, but i have some questions about each that were troubling me:

Magmai: Obviously i''d thought about abstract classes and virtual functions etc, but I want to be able to say

Matrix3 tempMatrix = new Matrix3;

and not

if AMD
Matrix3 tempMatrix = new AMDMatrix3;
else if INTEL
Matrix3 tempMatrix = new INTELMatrix3

if you see what i mean, and the abstract classes and virtual functions route seems to suggest i have to do it this way. This was what I was talking about when I said not using if''s ealier.

CGameProgrammer: Hehe, I hadn''t actually thought about just using different executables....

A person: Aha.. overloading new... have to look into that.. but surely if I want to do

Matrix3 tempMatrix = new Matrix3;

and have it decide then it won''t work still because you can''t instantiate an abstract class or interface? and so the compiler will complain?


tangentz: Hey, yeah! I could use DLLs, but then you can''t do what I wanted with a class in a dll... Don''t forget you create the class from within the dll, and free it in there too. So i''d have to have a function like CreateMatrix() and do this:

Matrix3 tempMatrix = CreateMatrix();

Plus, for dlls, I have to use virtual functions for which there is an overhead, plus there is overhead for calling a dll function... I know I can''t get around the virtual function overhead, but i''d like to minimize the cost because otherwise i''ll negate the benefits of the optimization....

Share this post


Link to post
Share on other sites
quote:
Original post by Jx
tangentz: Hey, yeah! I could use DLLs, but then you can''t do what I wanted with a class in a dll... Don''t forget you create the class from within the dll, and free it in there too. So i''d have to have a function like CreateMatrix() and do this:

Matrix3 tempMatrix = CreateMatrix();



Hmm... I see no reason why you''d have to do this. As long
as you "new" and "delete" the Matrix in the same place (app
or DLL), you''d be okay. So you don''t need CreateMatrix().
Since Matrix is so simple, I doubt there''s any trouble
making sure that is the case.

  
// Inside Matrix.dll

class DLLEXPORT Matrix
{
double m_Matirx[16];
// Plus the member functions

};
// end class



// Inside main application

Matrix *pMat = new Matrix;
// ...

delete pMat;

// Or simply,

Matrix Mat;


quote:
Original post by Jx
Plus, for dlls, I have to use virtual functions for which there is an overhead, plus there is overhead for calling a dll function... I know I can''t get around the virtual function overhead, but i''d like to minimize the cost because otherwise i''ll negate the benefits of the optimization....



Virtual functions? No, you don''t need them.

Hmm... once the DLL is loaded (which happens during app
initilizationg), it''s in memory. You call the functions
just like any other ordinary functions. There''s no calling
overhead.

So, I really don''t see why you can''t use DLL for your
problem.


Premature optimizations can only slow down your project even more.

Share this post


Link to post
Share on other sites
tangentz:
quote:

Virtual functions? No, you don't need them.



I don't understand how you think I can work this without virtual functions. What happens if i want this function somewhere else in my code:

RotateWorld(Matrix *TheMatrix);

Now if i have different .DLLs for the different processors - which is fine - i'm going to have to have some base Matrix class from which I derive AMDMatrix and INTELMatrix so I can have a generic function like that. In which case, in the generic base class i need something like:

    
class Matrix
{
public:

virtual ~Matrix( );

virtual mult( const Matrix& mat ) = 0;

...
etc
...
};



If i didn't have a generic base class, I would have to write 3 or more functions - one for each type of matrix right?

Also what happens if I don't want to link with the lib file for the dll. Every time i try and create a type of say AMDMatrix, i'll get an error from the linker.

quote:

Hmm... I see no reason why you'd have to do this. As long
as you "new" and "delete" the Matrix in the same place (app
or DLL), you'd be okay. So you don't need CreateMatrix().
Since Matrix is so simple, I doubt there's any trouble
making sure that is the case.



Ok - take a look at this:

Game Programming Gems 2 Section 1.4, Page 19:

quote:

There is one potential problem with declaring or allocating a class exported from a DLL in an application: it may confuse some memory-tracking programs and cause them to misreport memory allocations or deletions. To fix this problem, helper functions that allocate and destory instances of the exported class must be added to the DLL. All users of the exported class should call the allocation function to create and instance of it.



Also, looking at this article on GameDev
http://www.gamedev.net/reference/articles/article928.asp

they use the same approach and have two functions for allocation and deletion.



Edit: Added the bit about linker errors...

Edited by - Jx on February 19, 2002 11:51:13 AM

Share this post


Link to post
Share on other sites
quote:
Original post by Jx
I don't understand how you think I can work this without virtual functions. What happens if i want this function somewhere else in my code:



I thought I was pretty clear on how to do this, but I'll
try to explain again.

quote:
Original post by Jx
RotateWorld(Matrix *TheMatrix);

Now if i have different .DLLs for the different processors - which is fine - i'm going to have to have some base Matrix class from which I derive AMDMatrix and INTELMatrix so I can have a generic function like that. In which case, in the generic base class i need something like:



No, no, that's not it. Your AMDMatrix and INTELMatrix
are BOTH simply called "Matrix". In the AMD\Matrix.dll,
the Matrix class implements operations using AMD instructions
while in the Intel\Matrix.dll, the Matrix class implements
using Intel instructions. There is one and only one
class, namely, Matrix. It is a concrete class.

      
// In AMD\Matrix.dll

class DLLEXPORT Matrix
{
// Use AMD instructions

};
// end



// In Intel\Matrix.dll

class DLLEXPORT Matrix
{
// Use Intel instructions

};
// end



quote:
Original post by Jx
I don't understand how you think I can work this without virtual functions. What happens if i want this function somewhere else in my code:


         
RotateWorld(Matrix *TheMatrix);


Sure, why not? Matrix * simply means a pointer to a Matrix
object. So make one and pass it to RotateWorld().

quote:

If i didn't have a generic base class, I would have to write 3 or more functions - one for each type of matrix right?



Not sure what you mean. Surely you have Rotate, Translate,
Invert, Transpose... etc.. as public functions. That's
*the* interface for using the Matrix class. You can add
different private functions in AMD\Matrix and Intel\Matrix
to implement their specific functionalities.

quote:
Original post by Jx
Ok - take a look at this:

Game Programming Gems 2 Section 1.4, Page 19:

[quote]
There is one potential problem with declaring or allocating a class exported from a DLL in an application: it may confuse some memory-tracking programs and cause them to misreport memory allocations or deletions. To fix this problem, helper functions that allocate and destory instances of the exported class must be added to the DLL. All users of the exported class should call the allocation function to create and instance of it.



That's a fair warning for complex classes that allocate
their own memory/resource. But Matrix is so simple, there's
not much to worry about.

quote:
Original post by Jx
Also, looking at this article on GameDev
http://www.gamedev.net/reference/articles/article928.asp

they use the same approach and have two functions for allocation and deletion.



Again, fair warning for complex classes. For this specific
case of Matrix, there's nothing to worry about.

The quoted articles describe good techniques to avoid the
pitfalls. But that's only half of the whole picture. They
explain the HOW-TO. The other half is to understand WHEN-TO.
Apply techniques WHEN they make sense.

Premature optimizations can only slow down your project even more.

Edited by - tangentz on February 19, 2002 12:00:46 PM

Edited by - tangentz on February 19, 2002 12:02:33 PM

Share this post


Link to post
Share on other sites
Doesn''t that example fail when you want to link with the libs for the .dlls because Matrix is define twice?

Think so....

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!