106 lines
4.6 KiB
C++
106 lines
4.6 KiB
C++
/*
|
|
Copyright (c) 2005-2020 Intel Corporation
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
#include "common.h"
|
|
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
// The performance of this example can be significantly better when
|
|
// the objects are allocated by the scalable_allocator instead of the
|
|
// default "operator new". The reason is that the scalable_allocator
|
|
// typically packs small objects more tightly than the default "operator new",
|
|
// resulting in a smaller memory footprint, and thus more efficient use of
|
|
// cache and virtual memory. Also the scalable_allocator works faster for
|
|
// multi-threaded allocations.
|
|
//
|
|
// Pass stdmalloc as the 1st command line parameter to use the default "operator new"
|
|
// and see the performance difference.
|
|
#include "tbb/scalable_allocator.h"
|
|
#include "tbb/global_control.h"
|
|
#include "TreeMaker.h"
|
|
#include "tbb/tick_count.h"
|
|
|
|
#include "../../common/utility/utility.h"
|
|
#include "../../common/utility/get_default_num_threads.h"
|
|
|
|
using namespace std;
|
|
|
|
void Run( const char* which, Value(*SumTree)(TreeNode*), TreeNode* root, bool silent) {
|
|
tbb::tick_count t0;
|
|
if ( !silent ) t0 = tbb::tick_count::now();
|
|
Value result = SumTree(root);
|
|
if ( !silent ) printf ("%24s: time = %.1f msec, sum=%g\n", which, (tbb::tick_count::now()-t0).seconds()*1000, result);
|
|
}
|
|
|
|
int main( int argc, const char *argv[] ) {
|
|
try{
|
|
tbb::tick_count mainStartTime = tbb::tick_count::now();
|
|
|
|
// The 1st argument is the function to obtain 'auto' value; the 2nd is the default value
|
|
// The example interprets 0 threads as "run serially, then fully subscribed"
|
|
utility::thread_number_range threads( utility::get_default_num_threads, 0 );
|
|
long number_of_nodes = 10000000;
|
|
bool silent = false;
|
|
bool use_stdmalloc = false;
|
|
|
|
utility::parse_cli_arguments(argc,argv,
|
|
utility::cli_argument_pack()
|
|
//"-h" option for displaying help is present implicitly
|
|
.positional_arg(threads,"n-of-threads",utility::thread_number_range_desc)
|
|
.positional_arg(number_of_nodes,"number-of-nodes","the number of nodes")
|
|
.arg(silent,"silent","no output except elapsed time")
|
|
.arg(use_stdmalloc,"stdmalloc","use standard allocator")
|
|
);
|
|
|
|
TreeNode* root;
|
|
{ // In this scope, TBB will use default number of threads for tree creation
|
|
tbb::global_control c(tbb::global_control::max_allowed_parallelism, utility::get_default_num_threads());
|
|
|
|
if( use_stdmalloc ) {
|
|
if ( !silent ) printf("Tree creation using standard operator new\n");
|
|
root = TreeMaker<stdmalloc>::create_and_time( number_of_nodes, silent );
|
|
} else {
|
|
if ( !silent ) printf("Tree creation using TBB scalable allocator\n");
|
|
root = TreeMaker<tbbmalloc>::create_and_time( number_of_nodes, silent );
|
|
}
|
|
}
|
|
|
|
// Warm up caches
|
|
SerialSumTree(root);
|
|
if ( !silent ) printf("Calculations:\n");
|
|
if ( threads.first ) {
|
|
for(int p = threads.first; p <= threads.last; p = threads.step(p) ) {
|
|
if ( !silent ) printf("threads = %d\n", p );
|
|
tbb::global_control c(tbb::global_control::max_allowed_parallelism, p);
|
|
Run ( "SimpleParallelSumTree", SimpleParallelSumTree, root, silent );
|
|
Run ( "OptimizedParallelSumTree", OptimizedParallelSumTree, root, silent );
|
|
}
|
|
} else { // Number of threads wasn't set explicitly. Run serial and two parallel versions
|
|
Run ( "SerialSumTree", SerialSumTree, root, silent );
|
|
tbb::global_control c(tbb::global_control::max_allowed_parallelism, utility::get_default_num_threads());
|
|
Run ( "SimpleParallelSumTree", SimpleParallelSumTree, root, silent );
|
|
Run ( "OptimizedParallelSumTree", OptimizedParallelSumTree, root, silent );
|
|
}
|
|
utility::report_elapsed_time((tbb::tick_count::now() - mainStartTime).seconds());
|
|
return 0;
|
|
}catch(std::exception& e){
|
|
std::cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
|
|
return 1;
|
|
}
|
|
}
|