mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
(based on cipherCOM's repo commit e8a538e) Signed-off-by: VladimirMangos <vladimir@getmangos.com>
159 lines
4.8 KiB
C++
159 lines
4.8 KiB
C++
/*
|
|
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.
|
|
*/
|
|
|
|
#include <cstddef>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <float.h>
|
|
#include <math.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
|
|
#include <omp.h>
|
|
#include <assert.h>
|
|
|
|
#include "thread_level.h"
|
|
#define LOG_THREADS
|
|
|
|
#include "tbb/task.h"
|
|
#include "tbb/tick_count.h"
|
|
#include "tbb/task_scheduler_init.h"
|
|
#include "tbb/scalable_allocator.h"
|
|
#include "tbb/parallel_for.h"
|
|
#include "tbb/blocked_range.h"
|
|
|
|
using namespace std;
|
|
using namespace tbb;
|
|
|
|
// Algorithm parameters
|
|
const int Max_TBB_Threads = 16;
|
|
const int Max_OMP_Threads = 16;
|
|
|
|
// Global variables
|
|
int max_tbb_threads = Max_TBB_Threads;
|
|
int max_omp_threads = Max_OMP_Threads;
|
|
|
|
// Print help on command-line arguments
|
|
void help_message(char *prog_name) {
|
|
fprintf(stderr, "\n%s usage:\n", prog_name);
|
|
fprintf(stderr,
|
|
" Parameters:\n"
|
|
" -t<num> : max # of threads TBB should use\n"
|
|
" -o<num> : max # of threads OMP should use\n"
|
|
"\n Help:\n"
|
|
" -h : print this help message\n");
|
|
}
|
|
|
|
// Process command-line arguments
|
|
void process_args(int argc, char *argv[], int *max_tbb_t, int *max_omp_t) {
|
|
for (int i=1; i<argc; ++i) {
|
|
if (argv[i][0] == '-') {
|
|
switch (argv[i][1]) {
|
|
case 't': // set max_tbb_threads
|
|
if (sscanf(&argv[i][2], "%d", max_tbb_t) != 1 || *max_tbb_t < 1) {
|
|
fprintf(stderr, "%s Warning: argument of -t option unacceptable: %s\n", argv[0], &argv[i][2]);
|
|
help_message(argv[0]);
|
|
}
|
|
break;
|
|
case 'o': // set max_omp_threads
|
|
if (sscanf(&argv[i][2], "%d", max_omp_t) != 1 || *max_omp_t < 1) {
|
|
fprintf(stderr, "%s Warning: argument of -o option unacceptable: %s\n", argv[0], &argv[i][2]);
|
|
help_message(argv[0]);
|
|
}
|
|
break;
|
|
case 'h': // print help message
|
|
help_message(argv[0]);
|
|
exit(0);
|
|
break;
|
|
default:
|
|
fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]);
|
|
help_message(argv[0]);
|
|
break;
|
|
}
|
|
} else {
|
|
fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]);
|
|
help_message(argv[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
process_args(argc, argv, &max_tbb_threads, &max_omp_threads);
|
|
TotalThreadLevel.init();
|
|
|
|
tick_count start, end;
|
|
start = tick_count::now();
|
|
|
|
#pragma omp parallel num_threads(max_omp_threads)
|
|
{
|
|
int omp_thread = omp_get_thread_num();
|
|
#ifdef LOG_THREADS
|
|
if (omp_thread == 0)
|
|
TotalThreadLevel.change_level(omp_get_num_threads(), omp_outer);
|
|
#endif
|
|
task_scheduler_init phase(max_tbb_threads);
|
|
if (omp_thread == 0) {
|
|
sleep(3);
|
|
#ifdef LOG_THREADS
|
|
TotalThreadLevel.change_level(-1, omp_outer);
|
|
#endif
|
|
parallel_for(blocked_range<size_t>(0, 1000),
|
|
[=](const blocked_range<size_t>& range) {
|
|
#ifdef LOG_THREADS
|
|
TotalThreadLevel.change_level(1, tbb_inner);
|
|
#endif
|
|
#pragma ivdep
|
|
for (size_t i=range.begin(); i!=range.end(); ++i) {
|
|
if (i==range.begin())
|
|
printf("TBB range starting at %d on OMP thread %d\n", (int)i, omp_thread);
|
|
}
|
|
#ifdef LOG_THREADS
|
|
TotalThreadLevel.change_level(-1, tbb_inner);
|
|
#endif
|
|
}, auto_partitioner());
|
|
#ifdef LOG_THREADS
|
|
TotalThreadLevel.change_level(1, omp_outer);
|
|
#endif
|
|
}
|
|
else {
|
|
sleep(6);
|
|
}
|
|
#ifdef LOG_THREADS
|
|
if (omp_thread == 0)
|
|
TotalThreadLevel.change_level(-omp_get_num_threads(), omp_outer);
|
|
#endif
|
|
}
|
|
end = tick_count::now();
|
|
printf("Simple test of OMP (%d threads max) with TBB (%d threads max) inside took: %6.6f\n",
|
|
max_omp_threads, max_tbb_threads, (end-start).seconds());
|
|
#ifdef LOG_THREADS
|
|
TotalThreadLevel.dump();
|
|
#endif
|
|
return 0;
|
|
}
|