Memory allocation performance problems vs .net

G

Guest

We have been trying to upgrade all our C++ projects from VC6 to VS .Net2003
for a while (before VS 2005 arrived), and seem to be stuck now because of the
performance degradation seen for the same code when compiled by the new
compiler compared to being compiled by VC 6 compiler.
Originally we thought it was the STL libraries that had killed all
performance but it seems to be a general memory allocation problem in VS .Net
2003 (and also in VS 2005). Not only is the performance very poor in
comparison but seems to be inconsistent for timings too. When running the
code listed below on VS 6 both sets of timings are about the same, when
running on VS .Net (2003 and 2005) the timings are very much slower than
before but also inconsistent, then second set of output results are between
one and half to twice as slow as the first set. Please can someone explain
why this would be?

Below is the code snippet, which can be compilied under any of the dev
environments using any of the projects options you feel like, and either
debug or release, as long as you compare lilke with like you will same the
results as below).
The results shown here are comparing vc7.1 and vc6 release builds statically
linked with multi-threaded libraries:

VC 7.1
Old STL allocator test results.
Inserts = 3500ms
Lookups = 1312ms
Deletions = 844ms
Overall = 5656ms.
Old STL allocator test results.
Inserts = 4953ms
Lookups = 2860ms
Deletions = 843ms
Overall = 8656ms.

vc6
Old STL allocator test results.
Inserts = 1062ms
Lookups = 219ms
Deletions = 859ms
Overall = 2140ms.
Old STL allocator test results.
Inserts = 1172ms
Lookups = 203ms
Deletions = 875ms
Overall = 2250ms.

Source code:

#include <windows.h>
#include <iostream>
#include <set>

typedef std::set<DWORD, std::less<DWORD> >
COldSTLSet;

void STLTest1(DWORD dwIterations)
{
DWORD dwStart, dwStep1, dwStep2, dwEnd;
DWORD dwIndex;

// now use our own allocator object for an STL implementation
COldSTLSet SetTest1;

COldSTLSet::iterator iter1;

dwStart = GetTickCount();

// Old STL allocator type
// Insert items
for (dwIndex = 0;dwIndex < dwIterations;dwIndex++)
SetTest1.insert(dwIndex);

dwStep1 = GetTickCount();

// Lookup items
for (dwIndex = 0;dwIndex < dwIterations;dwIndex++)
{
iter1 = SetTest1.find(dwIndex);
if (iter1 == SetTest1.end())
std::cout << "Lookup failed.\n";
}
dwStep2 = GetTickCount();

// Delete items
while(!SetTest1.empty())
{
iter1 = SetTest1.begin();
SetTest1.erase(iter1);
}
dwEnd = GetTickCount();

std::cout << "Old STL allocator test results.\nInserts = " << dwStep1 -
dwStart << "ms\nLookups = " << dwStep2 - dwStep1 << "ms\nDeletions = " <<
dwEnd - dwStep2 << "ms\nOverall = " << dwEnd - dwStart << "ms.\n";
// End old stl allocator test
}

int main(int argc, char* argv[])
{
DWORD dwIterations = 1500000;
STLTest1(dwIterations);
Sleep(5000);
STLTest1(dwIterations);
return 0;
}
 
C

Carl Daniel [VC++ MVP]

EasyKev said:
We have been trying to upgrade all our C++ projects from VC6 to VS
.Net2003 for a while (before VS 2005 arrived), and seem to be stuck
now because of the performance degradation seen for the same code
when compiled by the new compiler compared to being compiled by VC 6
compiler.
Originally we thought it was the STL libraries that had killed all
performance but it seems to be a general memory allocation problem in
VS .Net 2003 (and also in VS 2005). Not only is the performance very
poor in comparison but seems to be inconsistent for timings too. When
running the code listed below on VS 6 both sets of timings are about
the same, when running on VS .Net (2003 and 2005) the timings are
very much slower than before but also inconsistent, then second set
of output results are between one and half to twice as slow as the
first set. Please can someone explain why this would be?

Below is the code snippet, which can be compilied under any of the dev
environments using any of the projects options you feel like, and
either debug or release, as long as you compare lilke with like you
will same the results as below).
The results shown here are comparing vc7.1 and vc6 release builds
statically linked with multi-threaded libraries:

Others have reported similar differences and have found that changing the
small block heap threshold solved the performance difference. See

http://msdn2.microsoft.com/en-us/library/a6x53890.aspx

while this link doesn't say, I believe that the defaults changed between VC6
and VC7 and that that's the source of most allocation-related performance
differences when porting from VC6.

-cd
 
S

Serge Skorokhodov (216716244)

Hi,

Others have reported similar differences and have found that
changing the small block heap threshold solved the performance
difference. See

http://msdn2.microsoft.com/en-us/library/a6x53890.aspx

Here the results of the original snippet on my machine:

Old STL allocator test results.
Inserts = 1328ms
Lookups = 593ms
Deletions = 485ms
Overall = 2406ms.
Old STL allocator test results.
Inserts = 4422ms
Lookups = 2531ms
Deletions = 469ms
Overall = 7422ms.

And this is output after _set_sbh_threshold(1016) addition in main:

Old STL allocator test results.
Inserts = 594ms
Lookups = 203ms
Deletions = 219ms
Overall = 1016ms.
Old STL allocator test results.
Inserts = 531ms
Lookups = 172ms
Deletions = 235ms
Overall = 938ms.
 
G

Guest

Thank you both for your replies to this.

We have tried this in one of our applications. It does improve the
performance for VC7.1 and VC8 applications for the majority of situations and
we will use this to resolve these issues.

The problem that I unfortunately have not been able to track down is under
some other circumstances the performance actually drops off when using the
_set_sbh_threshold. If and when I can track down the circumstances when the
drop occurs I will post again, with some sample code to replicate this
problem.

Thanks,

Kevin
 
Top