mirror of
https://github.com/mangosfour/server.git
synced 2026-01-02 01:37:05 +00:00
[11164] Changed TBB lib to same version but with make script
(based on cipherCOM's repo commit e8a538e) Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
cc8a11bff7
commit
21794edc44
38 changed files with 5517 additions and 579 deletions
366
dep/tbb/src/perf/time_hash_map.cpp
Normal file
366
dep/tbb/src/perf/time_hash_map.cpp
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
Copyright 2005-2009 Intel Corporation. All Rights Reserved.
|
||||
|
||||
This file is part of Threading Building Blocks.
|
||||
|
||||
Threading Building Blocks is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
|
||||
Threading Building Blocks is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Threading Building Blocks; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
As a special exception, you may use this file as part of a free software
|
||||
library without restriction. Specifically, if other files instantiate
|
||||
templates or use macros or inline functions from this file, or you compile
|
||||
this file and link it with other files to produce an executable, this
|
||||
file does not by itself cause the resulting executable to be covered by
|
||||
the GNU General Public License. This exception does not however
|
||||
invalidate any other reasons why the executable file might be covered by
|
||||
the GNU General Public License.
|
||||
*/
|
||||
|
||||
// configuration:
|
||||
|
||||
//! enable/disable std::map tests
|
||||
#define STDTABLE 1
|
||||
|
||||
//! enable/disable old implementation tests (correct include file also)
|
||||
#define OLDTABLE 0
|
||||
#define OLDTABLEHEADER "tbb/concurrent_hash_map-4078.h"//-4329
|
||||
|
||||
//! enable/disable experimental implementation tests (correct include file also)
|
||||
|
||||
#define TESTTABLE 0
|
||||
#define TESTTABLEHEADER "tbb/concurrent_unordered_map.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstdlib>
|
||||
#include <math.h>
|
||||
#include "tbb/tbb_stddef.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
// needed by hash_maps
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <algorithm> // std::swap
|
||||
#include <utility> // Need std::pair from here
|
||||
#include "tbb/cache_aligned_allocator.h"
|
||||
#include "tbb/tbb_allocator.h"
|
||||
#include "tbb/spin_rw_mutex.h"
|
||||
#include "tbb/aligned_space.h"
|
||||
#include "tbb/atomic.h"
|
||||
// for test
|
||||
#include "tbb/spin_mutex.h"
|
||||
#include "time_framework.h"
|
||||
|
||||
|
||||
using namespace tbb;
|
||||
using namespace tbb::internal;
|
||||
|
||||
struct IntHashCompare {
|
||||
size_t operator() ( int x ) const { return x; }
|
||||
bool operator() ( int x, int y ) const { return x==y; }
|
||||
static long hash( int x ) { return x; }
|
||||
bool equal( int x, int y ) const { return x==y; }
|
||||
};
|
||||
|
||||
namespace version_current {
|
||||
namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } }
|
||||
#include "tbb/concurrent_hash_map.h"
|
||||
}
|
||||
typedef version_current::tbb::concurrent_hash_map<int,int,IntHashCompare> IntTable;
|
||||
|
||||
#if OLDTABLE
|
||||
#undef __TBB_concurrent_hash_map_H
|
||||
namespace version_base {
|
||||
namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } }
|
||||
#include OLDTABLEHEADER
|
||||
}
|
||||
typedef version_base::tbb::concurrent_hash_map<int,int,IntHashCompare> OldTable;
|
||||
#endif
|
||||
|
||||
#if TESTTABLE
|
||||
#undef __TBB_concurrent_hash_map_H
|
||||
namespace version_new {
|
||||
namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } }
|
||||
#include TESTTABLEHEADER
|
||||
}
|
||||
typedef version_new::tbb::concurrent_unordered_map<int,int,IntHashCompare,IntHashCompare> TestTable;
|
||||
#define TESTTABLE 1
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
static const char *map_testnames[] = {
|
||||
"1.insert", "2.count(w/rehash)", "3.find/wr", "4.erase"
|
||||
};
|
||||
|
||||
template<typename TableType>
|
||||
struct TestTBBMap : TesterBase {
|
||||
typedef typename TableType::accessor accessor;
|
||||
typedef typename TableType::const_accessor const_accessor;
|
||||
TableType Table;
|
||||
int n_items;
|
||||
|
||||
TestTBBMap() : TesterBase(4) {}
|
||||
void init() { n_items = value/threads_count; }
|
||||
|
||||
std::string get_name(int testn) {
|
||||
return std::string(map_testnames[testn]);
|
||||
}
|
||||
|
||||
double test(int test, int t)
|
||||
{
|
||||
switch(test) {
|
||||
case 0: // fill
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
accessor a;
|
||||
Table.insert( a, i );
|
||||
a->second = 0;
|
||||
}
|
||||
break;
|
||||
case 1: // work1
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
size_t c = Table.count( i );
|
||||
ASSERT( c == 1, NULL);
|
||||
}
|
||||
break;
|
||||
case 2: // work2
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
accessor a;
|
||||
Table.find( a, i );
|
||||
ASSERT( !a->second, "A key should be incremented only once");
|
||||
a->second += 1;
|
||||
}
|
||||
break;
|
||||
case 3: // clean
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
ASSERT( Table.erase( i ), NULL);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename M>
|
||||
struct TestSTLMap : TesterBase {
|
||||
std::map<int, int> Table;
|
||||
M mutex;
|
||||
|
||||
int n_items;
|
||||
TestSTLMap() : TesterBase(4) {}
|
||||
void init() { n_items = value/threads_count; }
|
||||
|
||||
std::string get_name(int testn) {
|
||||
return std::string(map_testnames[testn]);
|
||||
}
|
||||
|
||||
double test(int test, int t)
|
||||
{
|
||||
switch(test) {
|
||||
case 0: // fill
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
typename M::scoped_lock with(mutex);
|
||||
Table[i] = 0;
|
||||
}
|
||||
break;
|
||||
case 1: // work1
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
typename M::scoped_lock with(mutex);
|
||||
size_t c = Table.count(i);
|
||||
ASSERT( c == 1, NULL);
|
||||
}
|
||||
break;
|
||||
case 2: // work2
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
typename M::scoped_lock with(mutex);
|
||||
Table[i] += 1;
|
||||
}
|
||||
break;
|
||||
case 3: // clean
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
typename M::scoped_lock with(mutex);
|
||||
Table.erase(i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class fake_mutex {
|
||||
int a;
|
||||
public:
|
||||
class scoped_lock {
|
||||
fake_mutex *p;
|
||||
|
||||
public:
|
||||
scoped_lock() {}
|
||||
scoped_lock( fake_mutex &m ) { p = &m; }
|
||||
~scoped_lock() { p->a = 0; }
|
||||
void acquire( fake_mutex &m ) { p = &m; }
|
||||
void release() { }
|
||||
};
|
||||
};
|
||||
|
||||
class test_hash_map : public TestProcessor {
|
||||
public:
|
||||
test_hash_map() : TestProcessor("test_hash_map") {}
|
||||
void factory(int value, int threads) {
|
||||
if(Verbose) printf("Processing with %d threads: %d...\n", threads, value);
|
||||
process( value, threads,
|
||||
#if STDTABLE
|
||||
run("std::map ", new NanosecPerValue<TestSTLMap<spin_mutex> >() ),
|
||||
#endif
|
||||
#if OLDTABLE
|
||||
run("old::hmap", new NanosecPerValue<TestTBBMap<OldTable> >() ),
|
||||
#endif
|
||||
run("tbb::hmap", new NanosecPerValue<TestTBBMap<IntTable> >() ),
|
||||
#if TESTTABLE
|
||||
run("new::hmap", new NanosecPerValue<TestTBBMap<TestTable> >() ),
|
||||
#endif
|
||||
end );
|
||||
//stat->Print(StatisticsCollector::Stdout);
|
||||
if(value >= 2097152) stat->Print(StatisticsCollector::HTMLFile);
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename TableType>
|
||||
struct TestHashMapFind : TesterBase {
|
||||
typedef typename TableType::accessor accessor;
|
||||
typedef typename TableType::const_accessor const_accessor;
|
||||
TableType Table;
|
||||
int n_items;
|
||||
|
||||
std::string get_name(int testn) {
|
||||
return std::string(!testn?"find":"insert");
|
||||
}
|
||||
|
||||
TestHashMapFind() : TesterBase(2) {}
|
||||
void init() {
|
||||
n_items = value/threads_count;
|
||||
for(int i = 0; i < value; i++) {
|
||||
accessor a; Table.insert( a, i );
|
||||
}
|
||||
}
|
||||
|
||||
double test(int test, int t)
|
||||
{
|
||||
switch(test) {
|
||||
case 0: // find
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
accessor a;
|
||||
Table.find( a, i );
|
||||
a->second = i;
|
||||
}
|
||||
break;
|
||||
case 1: // insert
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
accessor a;
|
||||
Table.insert( a, i );
|
||||
a->second = -i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
const int test2_size = 65536;
|
||||
int Data[test2_size];
|
||||
|
||||
template<typename TableType>
|
||||
struct TestHashCountStrings : TesterBase {
|
||||
typedef typename TableType::accessor accessor;
|
||||
typedef typename TableType::const_accessor const_accessor;
|
||||
TableType Table;
|
||||
int n_items;
|
||||
|
||||
std::string get_name(int testn) {
|
||||
return !testn?"insert":"find";
|
||||
}
|
||||
|
||||
TestHashCountStrings() : TesterBase(2) {}
|
||||
void init() {
|
||||
n_items = value/threads_count;
|
||||
}
|
||||
|
||||
double test(int testn, int t)
|
||||
{
|
||||
if(!testn) {
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
accessor a; Table.insert( a, Data[i] );
|
||||
}
|
||||
} else { //
|
||||
for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) {
|
||||
accessor a; Table.find( a, Data[i] );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class test_hash_map_find : public TestProcessor {
|
||||
public:
|
||||
test_hash_map_find() : TestProcessor("test_hash_map_find") {}
|
||||
void factory(int value, int threads) {
|
||||
if(Verbose) printf("Processing with %d threads: %d...\n", threads, value);
|
||||
process( value, threads,
|
||||
#if OLDTABLE
|
||||
run("Filled old::hashmap", new NanosecPerValue<TestHashMapFind<OldTable> >() ),
|
||||
#endif
|
||||
run("Filled tbb::hashmap", new NanosecPerValue<TestHashMapFind<IntTable> >() ),
|
||||
#if TESTTABLE
|
||||
run("Filled new::hashmap", new NanosecPerValue<TestHashMapFind<TestTable> >() ),
|
||||
#endif
|
||||
#if OLDTABLE
|
||||
run("CountStr old::hashmap", new TimeTest<TestHashCountStrings<OldTable> >() ),
|
||||
#endif
|
||||
run("CountStr tbb::hashmap", new TimeTest<TestHashCountStrings<IntTable> >() ),
|
||||
#if TESTTABLE
|
||||
run("CountStr new::hashmap", new TimeTest<TestHashCountStrings<TestTable> >() ),
|
||||
#endif
|
||||
end );
|
||||
//stat->Print(StatisticsCollector::HTMLFile);
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc>1) Verbose = true;
|
||||
//if(argc>2) ExtraVerbose = true;
|
||||
MinThread = 1; MaxThread = task_scheduler_init::default_num_threads();
|
||||
ParseCommandLine( argc, argv );
|
||||
|
||||
ASSERT(tbb_allocator<int>::allocator_type() == tbb_allocator<int>::scalable, "expecting scalable allocator library to be loaded. Please build it by:\n\t\tmake tbbmalloc");
|
||||
|
||||
{
|
||||
test_hash_map_find test_find; int o = test2_size;
|
||||
for(int i = 0; i < o; i++)
|
||||
Data[i] = i%60;
|
||||
for( int t=MinThread; t <= MaxThread; t++)
|
||||
test_find.factory(o, t);
|
||||
test_find.report.SetTitle("Nanoseconds per operation of finding operation (Mode) for %d items", o);
|
||||
test_find.report.Print(StatisticsCollector::HTMLFile|StatisticsCollector::ExcelXML);
|
||||
}
|
||||
{
|
||||
test_hash_map the_test;
|
||||
for( int t=MinThread; t <= MaxThread; t*=2)
|
||||
for( int o=/*2048*/(1<<8)*8; o<2200000; o*=2 )
|
||||
the_test.factory(o, t);
|
||||
the_test.report.SetTitle("Nanoseconds per operation of (Mode) for N items in container (Name)");
|
||||
the_test.report.SetStatisticFormula("1AVG per size", "=AVERAGE(ROUNDS)");
|
||||
the_test.report.Print(StatisticsCollector::HTMLFile|StatisticsCollector::ExcelXML);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue