Comments for Huh? http://phresnel.org/blog D'Oh! (feel free to leave me a mail at "phresnel.gmail@com , swap @ with . for proper mail) Mon, 29 Mar 2010 07:27:12 +0000 hourly 1 http://wordpress.org/?v=3.1.2 Comment on Virtual Functions Considered Not Harmful, Part I by phresnel http://phresnel.org/blog/2009/02/virtual-functions-considered-not-harmful-part-i/comment-page-1/#comment-11 phresnel Mon, 29 Mar 2010 07:27:12 +0000 http://phresnel.org/blog/?p=51#comment-11 Maciej: That's of course true. In very complex cases, the CPU will get into trouble. What I really wanted to show is that, if your code can signifcantly benefit from virtual functions, and if it is not too nested/complex, then you should consider using virtual functions. Maciej: That’s of course true. In very complex cases, the CPU will get into trouble. What I really wanted to show is that, if your code can signifcantly benefit from virtual functions, and if it is not too nested/complex, then you should consider using virtual functions.

]]>
Comment on Virtual Functions Considered Not Harmful, Part I by Maciej http://phresnel.org/blog/2009/02/virtual-functions-considered-not-harmful-part-i/comment-page-1/#comment-10 Maciej Mon, 29 Mar 2010 05:08:59 +0000 http://phresnel.org/blog/?p=51#comment-10 Interesting read but in my opinion your virtual function profiling is a bit incomplete. The real performance trouble with virtual functions shows up when you have more complex code than just simple vector operations and you're trashing your CPU caches (L1, L2) a lot. Imagine your CPU cache being completely invalidated - in that case before calling virtual function you must load virtual table to your cache first, then check address of the code to jump to, then load function to your cache. Non-virtual function call needs just an address. If your application has hundreds of classes with thousands of virtual functions being called in random order all over the time, then you're likely to be experiencing lots of cache misses for your virtual tables. Interesting read but in my opinion your virtual function profiling is a bit incomplete. The real performance trouble with virtual functions shows up when you have more complex code than just simple vector operations and you’re trashing your CPU caches (L1, L2) a lot.

Imagine your CPU cache being completely invalidated – in that case before calling virtual function you must load virtual table to your cache first, then check address of the code to jump to, then load function to your cache. Non-virtual function call needs just an address.

If your application has hundreds of classes with thousands of virtual functions being called in random order all over the time, then you’re likely to be experiencing lots of cache misses for your virtual tables.

]]>
Comment on This (->) is not only a matter of style. by phresnel http://phresnel.org/blog/2009/04/this-is-not-only-a-matter-of-style/comment-page-1/#comment-5 phresnel Fri, 12 Feb 2010 09:01:21 +0000 http://phresnel.org/blog/?p=99#comment-5 . Hello Hummm, the problem is less about when you call <b>X::vfun()</b>, but when you call a method of a derived class, i.e. <b>Y::fun()</b> (without the "v"), which in turn should call a virtual method. Take this updated snippet: <code>#include <iostream> void vfun() { std::cout << "::vfun()\n"; } template <typename T> struct X { virtual void vfun() const { std::cout << "X::vfun()\n"; } }; template <typename T> struct Y : public X<T> { // During compilation, only the global vfun() // is visible, so this will call ::vfun(). void fun0 () { vfun(); } // // This will explitily call X::vfun() // and inhibit virtual function dispatch. void fun1 () { X<T>::vfun(); } // // Qualifying the call with this makes the call // to vfun() "dependent", as the type of 'this' // depends on X<T>, which is not yet known. // Thus, the compiler will postpone // name-lookup until Phase 2 of template parsing. void fun2 () { this->vfun(); } }; template <typename T> struct Z : Y<T> { virtual void vfun() const { std::cout << "Z::vfun()\n"; } }; int main () { Z<int> z; z.fun0(); z.fun1(); z.fun2(); std::cout << std::flush; }</code> If you are using MSVC, make sure to disable C++ language extensions. .

Hello Hummm,

the problem is less about when you call X::vfun(), but when you call a method of a derived class, i.e. Y::fun() (without the “v”), which in turn should call a virtual method.

Take this updated snippet:

#include
void vfun() {
std::cout < < "::vfun()\n";
}
template struct X {
virtual void vfun() const { std::cout < < "X::vfun()\n"; }
};
template struct Y : public X {
// During compilation, only the global vfun()
// is visible, so this will call ::vfun().
void fun0 () { vfun(); }
//
// This will explitily call X::vfun()
// and inhibit virtual function dispatch.
void fun1 () { X
::vfun(); }
//
// Qualifying the call with this makes the call
// to vfun() "dependent", as the type of 'this'
// depends on X
, which is not yet known.
// Thus, the compiler will postpone
// name-lookup until Phase 2 of template parsing.
void fun2 () { this->vfun(); }
};
template struct Z : Y {
virtual void vfun() const { std::cout < < "Z::vfun()\n"; }
};
int main () {
Z z;
z.fun0();
z.fun1();
z.fun2();
std::cout < < std::flush;
}

If you are using MSVC, make sure to disable C++ language extensions.

]]>
Comment on This (->) is not only a matter of style. by Hummm http://phresnel.org/blog/2009/04/this-is-not-only-a-matter-of-style/comment-page-1/#comment-4 Hummm Fri, 12 Feb 2010 06:01:05 +0000 http://phresnel.org/blog/?p=99#comment-4 . I am maybe too noob in C++, but I didn't understand your statement "So, if we now call Z::vfun() through a pointer or reference to struct X, we really call X::vfun(), and not the overriden version in Z." I understood that C++ calls ::vfun() from Y::fun(); However, compiling your example and executing: X * x = &z; x->vfun(); returns "Z::vfun()n". Where is the problem? .

I am maybe too noob in C++, but I didn’t understand your statement “So, if we now call Z::vfun() through a pointer or reference to struct X, we really call X::vfun(), and not the overriden version in Z.”

I understood that C++ calls ::vfun() from Y::fun(); However, compiling your example and executing: X * x = &z; x->vfun(); returns “Z::vfun()n”. Where is the problem?

]]>