Jump to content
  • Advertisement
Sign in to follow this  
Prune

Any overhead when inheriting from class with only static members?

This topic is 2558 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 have a class A with only static members, where I want to lazily initialize said members: at first construction (if such even occurs) of an object from some other classes B, C... that rely on A being initialized, rather than during program startup. However, rather than calling A::Init() in the ctors of B, C..., I want that to happen automatically whenever an object of those classes is created. So I put the initialization in the ctor of A, and made B, C... derive from A. My question is whether there is any performance impact whatsoever of doing this, versus not having the inheritance and just calling A::Init() in the ctors explicitly instead. The sizes of B, C... of course are not impacted, and I don't think a vtable would be generated because there's no polymorphism possible, but I wanted to ask so I can be sure.

Share this post


Link to post
Share on other sites
Advertisement
The compiler should skip v-table generation if a class has no virtual functions. Compile your project with optimisations on and check the assembly code. This is the only way to ensure that the desired "micro optimisations" are actually being performed.

Share this post


Link to post
Share on other sites

Thanks.

Just wondering why you only have class static variables in the base class, do these need to be the same for all instances of the objects. Also bear in mind that when you change the value in either B or C instances the will change for all derived types using them and all existing instance.

Share this post


Link to post
Share on other sites
Yes, it's shared value. Basically it's just to lazy-initialize a handle to an NT keyed event, which I then use for the sleeping slow-path of various synchronization primitives like mutexes, condvars, and so on. I just didn't want to initialize it unless one of those dependent classes was actually used.

Share this post


Link to post
Share on other sites
There should be no performance penalty whatsoever (but then again, some compilers are weird.)

However, there are a couple of corner case caveats with this kind of lazy initialization. The first is that it's obviously not thread safe unless you've made it explicitly so. Second is that where initialization happens is unpredictable (although that is rarely an issue unless the Init function has serious side effects.) And the third caveat is that static variables are kind of funky if used eg. in a shared library (you could end up with duplicate values.)

Share this post


Link to post
Share on other sites
I have it in an atomic compare-exchange loop so it's thread safe. I'm just doing the equivalent of std::call_once() for initialization but instead of using a separate once_flag, I'm storing the flag in the pointer itself since no valid pointer will be 0 or 1. This saves space. (got the idea from singleton article at lockless inc site)
[source lang="cpp"]
void *cur(LoadAcq(_handle));
while (reinterpret_cast<unsigned long>(cur) <= 1) // While uninitialized or contended
{
if (!cur && !AtomicCAS(reinterpret_cast<unsigned long *>(&_handle), 0, 1)) // Try to set contended
{
try
{
void *temp(Init()); // Load ntdll and the relevant functions and create keyed event
StoreRel(_handle, temp);
return;
}
catch (...)
{
StoreRel(_handle, nullptr); // Other threads should be able to retry
throw;
}
}
Pause();
cur = LoadAcq(_handle);
}
[/source]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!