Why is VC8 code much slower than VC7.1?
-
Tuesday, May 10, 2005 4:41 PM
I have built the code below using both MSVC 7.1 and 8.0 beta 2, using the command shown in the initial comment. When run on a 3GHz P4 with 1GB RAM, running XP SP2, the output is as follows:
VC7.1: Time = 62
VC8.0: Time = 110Why does the 8.0 build take 1.77 times as long to run?
Thanks,
Keith MacDonald/////////////////////////////////
// cl -Ox -EHsc -MT TimeTest.cpp#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <vector>
#include <algorithm>class View;
class Document
{
public:
Document()
{}void Subscribe(View* pView)
{
m_subscribers.push_back(pView);
}void Unsubscribe(View* pView)
{
list_t::iterator it = std::find(m_subscribers.begin(), m_subscribers.end(), pView);if (it != m_subscribers.end())
m_subscribers.erase(it);
}void Notify() const;
private:
typedef std::vector<View*> list_t;
list_t m_subscribers;
};class View
{
public:
View(Document& m)
: m_document(m)
{
m_document.Subscribe(this);
}virtual ~View()
{
m_document.Unsubscribe(this);
}virtual void Update() = 0;
protected:
Document& m_document;
};class TextView : public View
{
public:
TextView(Document& m)
: View(m)
{ }virtual void Update()
{ }
};class HexView : public View
{
public:
HexView(Document& m)
: View(m)
{ }virtual void Update()
{ }
};void Document::Notify() const
{
for (list_t::const_iterator it = m_subscribers.begin(); it != m_subscribers.end(); ++it)
(*it)->Update();
}int main()
{
Document doc;
TextView v1(doc);
HexView v2(doc);
const DWORD dwTime = ::GetTickCount();for (int i = 0; i < 6000000; ++i)
doc.Notify();std::cout << "Time = " << ::GetTickCount() - dwTime << std::endl;
return 0;
}
Answers
-
Tuesday, May 10, 2005 6:48 PMModerator
Keith,
Thanks for the feedback. In the case of the standard C++ library, some of the checks we added were over-zealous in repeatedly re-verifying safety of algorithms. So for some cases you can see a large slowdown in beta 2 (larger than this, even.).
However, we are already working through fixes for these issues which will make it into the final product.
Martyn Lovell
Development Lead
Visual C++ Libraries -
Tuesday, May 10, 2005 7:25 PM
Martyn,
Thanks for your prompt response.
It's good to hear that you are working on these performance issues, but it looks like there's a lot of work to do. Most of the processor time in my sample is consumed by Document::Notify(), so based on your comments about the STD Library, I tried changing it to this:
void Document::Notify() const
{
for (size_t n = 0; n != m_subscribers.size(); ++n)
m_subscribers[ n ]->Update();
}
That increased the runtime from 110 to 141, so I then extracted the invariant part of the loop thus:
void Document::Notify() const
{
const size_t ncElems = m_subscribers.size();for (size_t n = 0; n != ncElems; ++n)
m_subscribers[ n ]->Update();
}
This got the time back to 110. As I'm compiling with /Ox, I'm very surprised that the optimiser doesn't handle that simple case already. (The optimiser has definitely not been disabled for the public beta, as with no optimisations, the time increases to 265.)
Maybe "Visual Studio 8" would be a safer name than "Visual Studio 2005", now that May is here.
Keith MacDonald -
Tuesday, September 27, 2005 9:24 PM
Keith,
In VC8.0 STL does lot of checks to minimize chances that you'll get buffer overruns, memory overwrites, etc. That is new feature that was requested by lot of customers, and it goes on nicely with other security enhancements we made in the product.
New STL is much safer than the old one; we (and our customers) found lot of problems in the programs that incorrectly used STL.
Those changes cause some overhead, and they can cause slowdown, especially in the small synthetic benchmarks, where all the time is spent in STL code itself. There are ways that allows compiler to remove some NULL and bounds checks (both libraries and compiler changes may be necessary), but unfortunately we didn't have enough time to fully address those issues. We will work on improving secure STL performance in the next VC version.
If you think you need the latest bit of performance, and you are ready to sacrify some security to achieve that performance, you can specify compiler flag
/D_SECURE_SCL=0
when compiling your application. That will turn security/safety chacks in STL headers, and its behavior will revert to pre-VC8.0 compiler.
Thanks,
Eugene
All Replies
-
Tuesday, May 10, 2005 6:48 PMModerator
Keith,
Thanks for the feedback. In the case of the standard C++ library, some of the checks we added were over-zealous in repeatedly re-verifying safety of algorithms. So for some cases you can see a large slowdown in beta 2 (larger than this, even.).
However, we are already working through fixes for these issues which will make it into the final product.
Martyn Lovell
Development Lead
Visual C++ Libraries -
Tuesday, May 10, 2005 7:25 PM
Martyn,
Thanks for your prompt response.
It's good to hear that you are working on these performance issues, but it looks like there's a lot of work to do. Most of the processor time in my sample is consumed by Document::Notify(), so based on your comments about the STD Library, I tried changing it to this:
void Document::Notify() const
{
for (size_t n = 0; n != m_subscribers.size(); ++n)
m_subscribers[ n ]->Update();
}
That increased the runtime from 110 to 141, so I then extracted the invariant part of the loop thus:
void Document::Notify() const
{
const size_t ncElems = m_subscribers.size();for (size_t n = 0; n != ncElems; ++n)
m_subscribers[ n ]->Update();
}
This got the time back to 110. As I'm compiling with /Ox, I'm very surprised that the optimiser doesn't handle that simple case already. (The optimiser has definitely not been disabled for the public beta, as with no optimisations, the time increases to 265.)
Maybe "Visual Studio 8" would be a safer name than "Visual Studio 2005", now that May is here.
Keith MacDonald -
Tuesday, May 10, 2005 9:12 PMvoid Document::Notify() const
{
for (size_t n = 0; n != m_subscribers.size(); ++n)
m_subscribers[ n ]->Update();
}
You are calling virtual function in the loop. Optimizer doesn't know if that call modifies m_subscribers, so it cannot hoist m_subscribers.size() out of the loop. -
Tuesday, September 27, 2005 5:49 PMMartyn,
I've just run the same test with VC8 RC1 that I did with beta 2 last May, and it still runs at half the speed of a VC 7.1 build. Is this as good as it's going to get?
Thanks,
Keith MacDonald -
Tuesday, September 27, 2005 9:24 PM
Keith,
In VC8.0 STL does lot of checks to minimize chances that you'll get buffer overruns, memory overwrites, etc. That is new feature that was requested by lot of customers, and it goes on nicely with other security enhancements we made in the product.
New STL is much safer than the old one; we (and our customers) found lot of problems in the programs that incorrectly used STL.
Those changes cause some overhead, and they can cause slowdown, especially in the small synthetic benchmarks, where all the time is spent in STL code itself. There are ways that allows compiler to remove some NULL and bounds checks (both libraries and compiler changes may be necessary), but unfortunately we didn't have enough time to fully address those issues. We will work on improving secure STL performance in the next VC version.
If you think you need the latest bit of performance, and you are ready to sacrify some security to achieve that performance, you can specify compiler flag
/D_SECURE_SCL=0
when compiling your application. That will turn security/safety chacks in STL headers, and its behavior will revert to pre-VC8.0 compiler.
Thanks,
Eugene -
Wednesday, September 28, 2005 8:51 AMEugene,
/D_SECURE_SCL=0 does exactly what I need.
Thanks,
Keith -
Tuesday, November 08, 2005 8:35 PMHey,
I have a similar problem of performance. My code (which is a genetic algorithm) is 3 times slower when compiled under Visual Studio 2005.
With Visual Studio 2003, it used to run in 3.0639 seconds, and now it runs in 9.0031 seconds. I tried every optimization option, and adding the /D_SECURE_SCL=0 compiler command to the project options with only minor differences.
Is there any other way to get back to the speed Visual Studio 2003 was giving? It is a bit absurd to upgrade to a new compiler and get lesser performances in the compiled program.
Thanks a lot!!!
Antoine Atallah -
Tuesday, November 08, 2005 8:41 PMModeratorHi Antoine,
I am actually interested in investigating such slow performance. Could you please post a sample exhibiting the problem? I will be more than happy to look at what is exactly happening.
Thanks,
Ayman Shoukry
VC++ Team

