Disabled external gits
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# 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.
|
||||
|
||||
# Common Makefile that builds and runs example.
|
||||
PROG=convex_hull_bench
|
||||
ARGS=
|
||||
PERF_RUN_ARGS = silent auto 40000000
|
||||
LIGHT_ARGS = 4 400
|
||||
|
||||
# Trying to find if icl.exe is set
|
||||
CXX1 = $(TBB_CXX)-
|
||||
CXX2 = $(CXX1:icl.exe-=icl.exe)
|
||||
CXX = $(CXX2:-=cl.exe)
|
||||
|
||||
# The C++ compiler options
|
||||
# Below, _SECURE_SCL=0 is for VC9 and earlier, and _ITERATOR_DEBUG_LEVEL=0 is for VC10 and later
|
||||
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _ITERATOR_DEBUG_LEVEL=0 /D _SECURE_SCL=0 $(CXXFLAGS)
|
||||
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
|
||||
|
||||
all: release test
|
||||
release: compiler_check
|
||||
$(CXX) convex_hull_sample.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:convex_hull_sample.exe
|
||||
$(CXX) convex_hull_bench.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:convex_hull_bench.exe
|
||||
debug: compiler_check
|
||||
$(CXX) convex_hull_sample.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:convex_hull_sample.exe
|
||||
$(CXX) convex_hull_bench.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:convex_hull_bench.exe
|
||||
clean:
|
||||
@cmd.exe /C del convex_hull*.exe *.obj *.?db *.manifest
|
||||
test:
|
||||
$(PROG) $(ARGS)
|
||||
perf_build: release
|
||||
|
||||
perf_run:
|
||||
convex_hull_sample $(PERF_RUN_ARGS)
|
||||
|
||||
light_test:
|
||||
$(PROG) $(LIGHT_ARGS)
|
||||
|
||||
compiler_check:
|
||||
@echo compiler_test>compiler_test && @$(CXX) /E compiler_test >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
|
||||
@cmd.exe /C del compiler_test
|
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __CONVEX_HULL_H__
|
||||
#define __CONVEX_HULL_H__
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <climits>
|
||||
#include "tbb/tick_count.h"
|
||||
#include "tbb/global_control.h"
|
||||
#include "../../common/utility/utility.h"
|
||||
#include "../../common/utility/get_default_num_threads.h"
|
||||
#include "../../common/utility/fast_random.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cfg {
|
||||
// convex hull problem user set parameters
|
||||
long numberOfPoints = 5000000; // problem size
|
||||
|
||||
// convex hull grain sizes for 3 subproblems. Be sure 16*GS < 512Kb
|
||||
const size_t generateGrainSize = 25000;
|
||||
const size_t findExtremumGrainSize = 25000;
|
||||
const size_t divideGrainSize = 25000;
|
||||
};
|
||||
|
||||
namespace util {
|
||||
bool silent = false;
|
||||
bool verbose = false;
|
||||
vector<string> OUTPUT;
|
||||
|
||||
// utility functionality
|
||||
void ParseInputArgs(int argc, char* argv[], utility::thread_number_range& threads) {
|
||||
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(cfg::numberOfPoints,"n-of-points","number of points")
|
||||
.arg(silent,"silent","no output except elapsed time")
|
||||
.arg(verbose,"verbose","turns verbose ON")
|
||||
);
|
||||
//disabling verbose if silent is specified
|
||||
if (silent) verbose = false;;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct point {
|
||||
T x;
|
||||
T y;
|
||||
//According to subparagraph 4 of paragraph 12.6.2 "Initializing bases and members" [class.base.init]
|
||||
//of ANSI-ISO-IEC C++ 2003 standard, POD members will _not_ be initialized if they are not mentioned
|
||||
//in the base-member initializer list.
|
||||
|
||||
//For more details why this needed please see comment in FillRNDPointsVector_buf
|
||||
point() {}
|
||||
point(T _x, T _y) : x(_x), y(_y) {}
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& o, point<double> const& p) {
|
||||
return o << "(" << p.x << "," << p.y << ")";
|
||||
}
|
||||
|
||||
struct rng {
|
||||
static const size_t max_rand = USHRT_MAX;
|
||||
utility::FastRandom my_fast_random;
|
||||
rng (size_t seed):my_fast_random(seed) {}
|
||||
unsigned short operator()(){return my_fast_random.get();}
|
||||
unsigned short operator()(size_t& seed){return my_fast_random.get(seed);}
|
||||
};
|
||||
|
||||
|
||||
template < typename T ,typename rng_functor_type>
|
||||
point<T> GenerateRNDPoint(size_t& count, rng_functor_type random, size_t rand_max) {
|
||||
/* generates random points on 2D plane so that the cluster
|
||||
is somewhat circle shaped */
|
||||
const size_t maxsize=500;
|
||||
T x = random()*2.0/(double)rand_max - 1;
|
||||
T y = random()*2.0/(double)rand_max - 1;
|
||||
T r = (x*x + y*y);
|
||||
if(r>1) {
|
||||
count++;
|
||||
if(count>10) {
|
||||
if (random()/(double)rand_max > 0.5)
|
||||
x /= r;
|
||||
if (random()/(double)rand_max > 0.5)
|
||||
y /= r;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
x /= r;
|
||||
y /= r;
|
||||
}
|
||||
}
|
||||
|
||||
x = (x+1)*0.5*maxsize;
|
||||
y = (y+1)*0.5*maxsize;
|
||||
|
||||
return point<T>(x,y);
|
||||
}
|
||||
|
||||
template <typename Index>
|
||||
struct edge {
|
||||
Index start;
|
||||
Index end;
|
||||
edge(Index _p1, Index _p2) : start(_p1), end(_p2) {};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
ostream& operator <<(ostream& _ostr, point<T> _p) {
|
||||
return _ostr << '(' << _p.x << ',' << _p.y << ')';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
istream& operator >>(istream& _istr, point<T> _p) {
|
||||
return _istr >> _p.x >> _p.y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator ==(point<T> p1, point<T> p2) {
|
||||
return (p1.x == p2.x && p1.y == p2.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator !=(point<T> p1, point<T> p2) {
|
||||
return !(p1 == p2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
double cross_product(const point<T>& start, const point<T>& end1, const point<T>& end2) {
|
||||
return ((end1.x-start.x)*(end2.y-start.y)-(end2.x-start.x)*(end1.y-start.y));
|
||||
}
|
||||
|
||||
// Timing functions are based on TBB to always obtain wall-clock time
|
||||
typedef tbb::tick_count my_time_t;
|
||||
|
||||
my_time_t gettime() {
|
||||
return tbb::tick_count::now();
|
||||
}
|
||||
|
||||
double time_diff(my_time_t start, my_time_t end) {
|
||||
return (end-start).seconds();
|
||||
}
|
||||
|
||||
void WriteResults(int nthreads, double initTime, double calcTime) {
|
||||
if(verbose) {
|
||||
cout << " Step by step hull construction:" << endl;
|
||||
for(size_t i = 0; i < OUTPUT.size(); ++i)
|
||||
cout << OUTPUT[i] << endl;
|
||||
}
|
||||
if (!silent){
|
||||
cout
|
||||
<< " Number of nodes:" << cfg::numberOfPoints
|
||||
<< " Number of threads:" << nthreads
|
||||
<< " Initialization time:" << setw(10) << setprecision(3) << initTime
|
||||
<< " Calculation time:" << setw(10) << setprecision(3) << calcTime
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CONVEX_HULL_H__
|
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file contains a few implementations, so it may look overly complicated.
|
||||
The most efficient implementation is also separated into convex_hull_sample.cpp
|
||||
*/
|
||||
#include "convex_hull.h"
|
||||
|
||||
typedef util::point<double> point_t;
|
||||
|
||||
#ifndef USETBB
|
||||
#define USETBB 1
|
||||
#endif
|
||||
#ifndef USECONCVEC
|
||||
#define USECONCVEC 1
|
||||
#endif
|
||||
|
||||
#if !USETBB // Serial implementation of Quick Hull algorithm
|
||||
|
||||
typedef std::vector< point_t > pointVec_t;
|
||||
|
||||
void serial_initialize(pointVec_t &points);
|
||||
|
||||
// C++ style serial code
|
||||
|
||||
class FindXExtremum : public std::unary_function<const point_t&, void> {
|
||||
public:
|
||||
typedef enum {
|
||||
minX, maxX
|
||||
} extremumType;
|
||||
|
||||
FindXExtremum(const point_t& frstPoint, extremumType exType_)
|
||||
: extrXPoint(frstPoint), exType(exType_) {}
|
||||
|
||||
void operator()(const point_t& p) {
|
||||
if(closerToExtremum(p))
|
||||
extrXPoint = p;
|
||||
}
|
||||
|
||||
operator point_t () {
|
||||
return extrXPoint;
|
||||
}
|
||||
|
||||
private:
|
||||
const extremumType exType;
|
||||
point_t extrXPoint;
|
||||
|
||||
bool closerToExtremum(const point_t &p) const {
|
||||
switch(exType) {
|
||||
case minX:
|
||||
return p.x<extrXPoint.x; break;
|
||||
case maxX:
|
||||
return p.x>extrXPoint.x; break;
|
||||
}
|
||||
return false; // avoid warning
|
||||
}
|
||||
};
|
||||
|
||||
template <FindXExtremum::extremumType type>
|
||||
point_t extremum(const pointVec_t &points) {
|
||||
assert(!points.empty());
|
||||
return std::for_each(points.begin(), points.end(), FindXExtremum(points[0], type));
|
||||
}
|
||||
|
||||
class SplitByCP : public std::unary_function<const point_t&, void> {
|
||||
pointVec_t &reducedSet;
|
||||
point_t p1, p2;
|
||||
point_t farPoint;
|
||||
double howFar;
|
||||
public:
|
||||
|
||||
SplitByCP( point_t _p1, point_t _p2, pointVec_t &_reducedSet)
|
||||
: p1(_p1), p2(_p2), reducedSet(_reducedSet), howFar(0), farPoint(p1) {}
|
||||
|
||||
void operator()(const point_t& p) {
|
||||
double cp;
|
||||
if( (p != p1) && (p != p2) ) {
|
||||
cp = util::cross_product(p1, p2, p);
|
||||
if(cp>0) {
|
||||
reducedSet.push_back(p);
|
||||
if(cp>howFar) {
|
||||
farPoint = p;
|
||||
howFar = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator point_t (){
|
||||
return farPoint;
|
||||
}
|
||||
};
|
||||
|
||||
point_t divide(const pointVec_t &P, pointVec_t &P_reduced, const point_t &p1, const point_t &p2) {
|
||||
SplitByCP splitByCP(p1, p2, P_reduced);
|
||||
point_t farPoint = std::for_each(P.begin(), P.end(), splitByCP);
|
||||
|
||||
if(util::verbose) {
|
||||
std::stringstream ss;
|
||||
ss << P.size() << " nodes in bucket"<< ", "
|
||||
<< "dividing by: [ " << p1 << ", " << p2 << " ], "
|
||||
<< "farthest node: " << farPoint;
|
||||
util::OUTPUT.push_back(ss.str());
|
||||
}
|
||||
|
||||
return farPoint;
|
||||
}
|
||||
|
||||
void divide_and_conquer(const pointVec_t &P, pointVec_t &H, point_t p1, point_t p2) {
|
||||
assert(P.size() >= 2);
|
||||
pointVec_t P_reduced;
|
||||
pointVec_t H1, H2;
|
||||
point_t p_far = divide(P, P_reduced, p1, p2);
|
||||
if (P_reduced.size()<2) {
|
||||
H.push_back(p1);
|
||||
H.insert(H.end(), P_reduced.begin(), P_reduced.end());
|
||||
}
|
||||
else {
|
||||
divide_and_conquer(P_reduced, H1, p1, p_far);
|
||||
divide_and_conquer(P_reduced, H2, p_far, p2);
|
||||
|
||||
H.insert(H.end(), H1.begin(), H1.end());
|
||||
H.insert(H.end(), H2.begin(), H2.end());
|
||||
}
|
||||
}
|
||||
|
||||
void quickhull(const pointVec_t &points, pointVec_t &hull) {
|
||||
if (points.size() < 2) {
|
||||
hull.insert(hull.end(), points.begin(), points.end());
|
||||
return;
|
||||
}
|
||||
point_t p_maxx = extremum<FindXExtremum::maxX>(points);
|
||||
point_t p_minx = extremum<FindXExtremum::minX>(points);
|
||||
|
||||
pointVec_t H;
|
||||
|
||||
divide_and_conquer(points, hull, p_maxx, p_minx);
|
||||
divide_and_conquer(points, H, p_minx, p_maxx);
|
||||
hull.insert(hull.end(), H.begin(), H.end());
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
util::ParseInputArgs(argc, argv);
|
||||
|
||||
pointVec_t points;
|
||||
pointVec_t hull;
|
||||
util::my_time_t tm_init, tm_start, tm_end;
|
||||
|
||||
std::cout << "Starting serial version of QUICK HULL algorithm" << std::endl;
|
||||
|
||||
tm_init = util::gettime();
|
||||
serial_initialize(points);
|
||||
tm_start = util::gettime();
|
||||
std::cout << "Init time: " << util::time_diff(tm_init, tm_start) << " Points in input: " << points.size() << "\n";
|
||||
tm_start = util::gettime();
|
||||
quickhull(points, hull);
|
||||
tm_end = util::gettime();
|
||||
std::cout << "Serial time: " << util::time_diff(tm_start, tm_end) << " Points in hull: " << hull.size() << "\n";
|
||||
}
|
||||
|
||||
#else // USETBB - parallel version of Quick Hull algorithm
|
||||
|
||||
#include "tbb/parallel_for.h"
|
||||
#include "tbb/parallel_reduce.h"
|
||||
#include "tbb/blocked_range.h"
|
||||
|
||||
typedef tbb::blocked_range<size_t> range_t;
|
||||
|
||||
#if USECONCVEC
|
||||
#include "tbb/concurrent_vector.h"
|
||||
|
||||
typedef tbb::concurrent_vector<point_t> pointVec_t;
|
||||
|
||||
void appendVector(const point_t* src, size_t srcSize, pointVec_t& dest) {
|
||||
std::copy(src, src + srcSize, dest.grow_by(srcSize));
|
||||
}
|
||||
|
||||
void appendVector(const pointVec_t& src, pointVec_t& dest) {
|
||||
std::copy(src.begin(), src.end(), dest.grow_by(src.size()));
|
||||
}
|
||||
|
||||
void grow_vector_to_at_least(pointVec_t& vect, size_t size) {
|
||||
vect.grow_to_at_least(size);
|
||||
}
|
||||
#else // USE STD::VECTOR - include spin_mutex.h and lock vector operations
|
||||
#include "tbb/spin_mutex.h"
|
||||
|
||||
typedef tbb::spin_mutex mutex_t;
|
||||
typedef std::vector<point_t> pointVec_t;
|
||||
|
||||
void appendVector(mutex_t& insertMutex, const pointVec_t& src, pointVec_t& dest) {
|
||||
mutex_t::scoped_lock lock(insertMutex);
|
||||
dest.insert(dest.end(), src.begin(), src.end());
|
||||
}
|
||||
|
||||
void appendVector(mutex_t& insertMutex, const point_t* src, size_t srcSize,
|
||||
pointVec_t& dest) {
|
||||
mutex_t::scoped_lock lock(insertMutex);
|
||||
dest.insert(dest.end(), src, src + srcSize);
|
||||
}
|
||||
|
||||
void grow_vector_to_at_least(mutex_t& mutex, pointVec_t& vect, size_t size) {
|
||||
mutex_t::scoped_lock lock(mutex);
|
||||
if (vect.size()< size){
|
||||
vect.resize(size);
|
||||
}
|
||||
}
|
||||
#endif // USECONCVEC
|
||||
|
||||
class FillRNDPointsVector {
|
||||
pointVec_t &points;
|
||||
public:
|
||||
static const size_t grainSize = cfg::generateGrainSize;
|
||||
#if !USECONCVEC
|
||||
static mutex_t pushBackMutex;
|
||||
#endif // USECONCVEC
|
||||
|
||||
explicit FillRNDPointsVector(pointVec_t& _points)
|
||||
: points(_points){}
|
||||
|
||||
void operator()(const range_t& range) const {
|
||||
util::rng the_rng(range.begin());
|
||||
const size_t i_end = range.end();
|
||||
size_t count = 0;
|
||||
#if USECONCVEC
|
||||
points.grow_to_at_least(i_end);
|
||||
#else // Locked enlarge to a not thread-safe STD::VECTOR
|
||||
grow_vector_to_at_least(pushBackMutex,points,i_end);
|
||||
#endif // USECONCVEC
|
||||
|
||||
for(size_t i = range.begin(); i != i_end; ++i) {
|
||||
points[i]=util::GenerateRNDPoint<double>(count,the_rng,util::rng::max_rand);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FillRNDPointsVector_buf {
|
||||
pointVec_t &points;
|
||||
public:
|
||||
static const size_t grainSize = cfg::generateGrainSize;
|
||||
#if !USECONCVEC
|
||||
static mutex_t insertMutex;
|
||||
#endif // USECONCVEC
|
||||
|
||||
explicit FillRNDPointsVector_buf(pointVec_t& _points)
|
||||
: points(_points){}
|
||||
|
||||
void operator()(const range_t& range) const {
|
||||
util::rng the_rng(range.begin());
|
||||
const size_t i_end = range.end();
|
||||
size_t count = 0, j = 0;
|
||||
point_t tmp_vec[grainSize];
|
||||
|
||||
for(size_t i=range.begin(); i!=i_end; ++i) {
|
||||
tmp_vec[j++] = util::GenerateRNDPoint<double>(count,the_rng,util::rng::max_rand);
|
||||
}
|
||||
#if USECONCVEC
|
||||
grow_vector_to_at_least(points,range.end());
|
||||
#else // USE STD::VECTOR
|
||||
grow_vector_to_at_least(insertMutex,points,range.end());
|
||||
#endif // USECONCVEC
|
||||
std::copy(tmp_vec, tmp_vec+j,points.begin()+range.begin());
|
||||
}
|
||||
};
|
||||
|
||||
#if !USECONCVEC
|
||||
mutex_t FillRNDPointsVector::pushBackMutex = mutex_t();
|
||||
mutex_t FillRNDPointsVector_buf::insertMutex = mutex_t();
|
||||
#endif
|
||||
|
||||
template<typename BodyType>
|
||||
void initialize(pointVec_t &points) {
|
||||
//This function generate the same series of point on every call.
|
||||
//Reproducibility is needed for benchmarking to produce reliable results.
|
||||
//It is achieved through the following points:
|
||||
// - FillRNDPointsVector_buf instance has its own local instance
|
||||
// of random number generator, which in turn does not use any global data
|
||||
// - tbb::simple_partitioner produce the same set of ranges on every call to
|
||||
// tbb::parallel_for
|
||||
// - local RNG instances are seeded by the starting indexes of corresponding ranges
|
||||
// - grow_to_at_least() enables putting points into the resulting vector in deterministic order
|
||||
// (unlike concurrent push_back or grow_by).
|
||||
|
||||
// In the buffered version, a temporary storage for as much as grainSize elements
|
||||
// is allocated inside the body. Since auto_partitioner may increase effective
|
||||
// range size which would cause a crash, simple partitioner has to be used.
|
||||
|
||||
tbb::parallel_for(range_t(0, cfg::numberOfPoints, BodyType::grainSize),
|
||||
BodyType(points), tbb::simple_partitioner());
|
||||
}
|
||||
|
||||
class FindXExtremum {
|
||||
public:
|
||||
typedef enum {
|
||||
minX, maxX
|
||||
} extremumType;
|
||||
|
||||
static const size_t grainSize = cfg::findExtremumGrainSize;
|
||||
|
||||
FindXExtremum(const pointVec_t& points_, extremumType exType_)
|
||||
: points(points_), exType(exType_), extrXPoint(points[0]) {}
|
||||
|
||||
FindXExtremum(const FindXExtremum& fxex, tbb::split)
|
||||
: points(fxex.points), exType(fxex.exType), extrXPoint(fxex.extrXPoint) {}
|
||||
|
||||
void operator()(const range_t& range) {
|
||||
const size_t i_end = range.end();
|
||||
if(!range.empty()) {
|
||||
for(size_t i = range.begin(); i != i_end; ++i) {
|
||||
if(closerToExtremum(points[i])) {
|
||||
extrXPoint = points[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void join(const FindXExtremum &rhs) {
|
||||
if(closerToExtremum(rhs.extrXPoint)) {
|
||||
extrXPoint = rhs.extrXPoint;
|
||||
}
|
||||
}
|
||||
|
||||
point_t extremeXPoint() {
|
||||
return extrXPoint;
|
||||
}
|
||||
|
||||
private:
|
||||
const pointVec_t &points;
|
||||
const extremumType exType;
|
||||
point_t extrXPoint;
|
||||
bool closerToExtremum(const point_t &p) const {
|
||||
switch(exType) {
|
||||
case minX:
|
||||
return p.x<extrXPoint.x; break;
|
||||
case maxX:
|
||||
return p.x>extrXPoint.x; break;
|
||||
}
|
||||
return false; // avoid warning
|
||||
}
|
||||
};
|
||||
|
||||
template <FindXExtremum::extremumType type>
|
||||
point_t extremum(const pointVec_t &P) {
|
||||
FindXExtremum fxBody(P, type);
|
||||
tbb::parallel_reduce(range_t(0, P.size(), FindXExtremum::grainSize), fxBody);
|
||||
return fxBody.extremeXPoint();
|
||||
}
|
||||
|
||||
class SplitByCP {
|
||||
const pointVec_t &initialSet;
|
||||
pointVec_t &reducedSet;
|
||||
point_t p1, p2;
|
||||
point_t farPoint;
|
||||
double howFar;
|
||||
public:
|
||||
static const size_t grainSize = cfg::divideGrainSize;
|
||||
#if !USECONCVEC
|
||||
static mutex_t pushBackMutex;
|
||||
#endif // USECONCVEC
|
||||
|
||||
SplitByCP( point_t _p1, point_t _p2,
|
||||
const pointVec_t &_initialSet, pointVec_t &_reducedSet)
|
||||
: p1(_p1), p2(_p2),
|
||||
initialSet(_initialSet), reducedSet(_reducedSet),
|
||||
howFar(0), farPoint(p1) {
|
||||
}
|
||||
|
||||
SplitByCP( SplitByCP& sbcp, tbb::split )
|
||||
: p1(sbcp.p1), p2(sbcp.p2),
|
||||
initialSet(sbcp.initialSet), reducedSet(sbcp.reducedSet),
|
||||
howFar(0), farPoint(p1) {}
|
||||
|
||||
void operator()( const range_t& range ) {
|
||||
const size_t i_end = range.end();
|
||||
double cp;
|
||||
for(size_t i=range.begin(); i!=i_end; ++i) {
|
||||
if( (initialSet[i] != p1) && (initialSet[i] != p2) ) {
|
||||
cp = util::cross_product(p1, p2, initialSet[i]);
|
||||
if(cp>0) {
|
||||
#if USECONCVEC
|
||||
reducedSet.push_back(initialSet[i]);
|
||||
#else // Locked push_back to a not thread-safe STD::VECTOR
|
||||
{
|
||||
mutex_t::scoped_lock lock(pushBackMutex);
|
||||
reducedSet.push_back(initialSet[i]);
|
||||
}
|
||||
#endif // USECONCVEC
|
||||
if(cp>howFar) {
|
||||
farPoint = initialSet[i];
|
||||
howFar = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void join(const SplitByCP& rhs) {
|
||||
if(rhs.howFar>howFar) {
|
||||
howFar = rhs.howFar;
|
||||
farPoint = rhs.farPoint;
|
||||
}
|
||||
}
|
||||
|
||||
point_t farthestPoint() const {
|
||||
return farPoint;
|
||||
}
|
||||
};
|
||||
|
||||
class SplitByCP_buf {
|
||||
const pointVec_t &initialSet;
|
||||
pointVec_t &reducedSet;
|
||||
point_t p1, p2;
|
||||
point_t farPoint;
|
||||
double howFar;
|
||||
public:
|
||||
static const size_t grainSize = cfg::divideGrainSize;
|
||||
#if !USECONCVEC
|
||||
static mutex_t insertMutex;
|
||||
#endif // USECONCVEC
|
||||
|
||||
SplitByCP_buf( point_t _p1, point_t _p2,
|
||||
const pointVec_t &_initialSet, pointVec_t &_reducedSet)
|
||||
: p1(_p1), p2(_p2),
|
||||
initialSet(_initialSet), reducedSet(_reducedSet),
|
||||
howFar(0), farPoint(p1) {}
|
||||
|
||||
SplitByCP_buf(SplitByCP_buf& sbcp, tbb::split)
|
||||
: p1(sbcp.p1), p2(sbcp.p2),
|
||||
initialSet(sbcp.initialSet), reducedSet(sbcp.reducedSet),
|
||||
howFar(0), farPoint(p1) {}
|
||||
|
||||
void operator()(const range_t& range) {
|
||||
const size_t i_end = range.end();
|
||||
size_t j = 0;
|
||||
double cp;
|
||||
point_t tmp_vec[grainSize];
|
||||
for(size_t i = range.begin(); i != i_end; ++i) {
|
||||
if( (initialSet[i] != p1) && (initialSet[i] != p2) ) {
|
||||
cp = util::cross_product(p1, p2, initialSet[i]);
|
||||
if(cp>0) {
|
||||
tmp_vec[j++] = initialSet[i];
|
||||
if(cp>howFar) {
|
||||
farPoint = initialSet[i];
|
||||
howFar = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if USECONCVEC
|
||||
appendVector(tmp_vec, j, reducedSet);
|
||||
#else // USE STD::VECTOR
|
||||
appendVector(insertMutex, tmp_vec, j, reducedSet);
|
||||
#endif // USECONCVEC
|
||||
}
|
||||
|
||||
void join(const SplitByCP_buf& rhs) {
|
||||
if(rhs.howFar>howFar) {
|
||||
howFar = rhs.howFar;
|
||||
farPoint = rhs.farPoint;
|
||||
}
|
||||
}
|
||||
|
||||
point_t farthestPoint() const {
|
||||
return farPoint;
|
||||
}
|
||||
};
|
||||
|
||||
#if !USECONCVEC
|
||||
mutex_t SplitByCP::pushBackMutex = mutex_t();
|
||||
mutex_t SplitByCP_buf::insertMutex = mutex_t();
|
||||
#endif
|
||||
|
||||
template <typename BodyType>
|
||||
point_t divide(const pointVec_t &P, pointVec_t &P_reduced,
|
||||
const point_t &p1, const point_t &p2) {
|
||||
BodyType body(p1, p2, P, P_reduced);
|
||||
// Must use simple_partitioner (see the comment in initialize() above)
|
||||
tbb::parallel_reduce(range_t(0, P.size(), BodyType::grainSize),
|
||||
body, tbb::simple_partitioner() );
|
||||
|
||||
if(util::verbose) {
|
||||
std::stringstream ss;
|
||||
ss << P.size() << " nodes in bucket"<< ", "
|
||||
<< "dividing by: [ " << p1 << ", " << p2 << " ], "
|
||||
<< "farthest node: " << body.farthestPoint();
|
||||
util::OUTPUT.push_back(ss.str());
|
||||
}
|
||||
|
||||
return body.farthestPoint();
|
||||
}
|
||||
|
||||
void divide_and_conquer(const pointVec_t &P, pointVec_t &H,
|
||||
point_t p1, point_t p2, bool buffered) {
|
||||
assert(P.size() >= 2);
|
||||
pointVec_t P_reduced;
|
||||
pointVec_t H1, H2;
|
||||
point_t p_far;
|
||||
|
||||
if(buffered) {
|
||||
p_far = divide<SplitByCP_buf>(P, P_reduced, p1, p2);
|
||||
} else {
|
||||
p_far = divide<SplitByCP>(P, P_reduced, p1, p2);
|
||||
}
|
||||
|
||||
if (P_reduced.size()<2) {
|
||||
H.push_back(p1);
|
||||
#if USECONCVEC
|
||||
appendVector(P_reduced, H);
|
||||
#else // insert into STD::VECTOR
|
||||
H.insert(H.end(), P_reduced.begin(), P_reduced.end());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
divide_and_conquer(P_reduced, H1, p1, p_far, buffered);
|
||||
divide_and_conquer(P_reduced, H2, p_far, p2, buffered);
|
||||
|
||||
#if USECONCVEC
|
||||
appendVector(H1, H);
|
||||
appendVector(H2, H);
|
||||
#else // insert into STD::VECTOR
|
||||
H.insert(H.end(), H1.begin(), H1.end());
|
||||
H.insert(H.end(), H2.begin(), H2.end());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void quickhull(const pointVec_t &points, pointVec_t &hull, bool buffered) {
|
||||
if (points.size() < 2) {
|
||||
#if USECONCVEC
|
||||
appendVector(points, hull);
|
||||
#else // STD::VECTOR
|
||||
hull.insert(hull.end(), points.begin(), points.end());
|
||||
#endif // USECONCVEC
|
||||
return;
|
||||
}
|
||||
|
||||
point_t p_maxx = extremum<FindXExtremum::maxX>(points);
|
||||
point_t p_minx = extremum<FindXExtremum::minX>(points);
|
||||
|
||||
pointVec_t H;
|
||||
|
||||
divide_and_conquer(points, hull, p_maxx, p_minx, buffered);
|
||||
divide_and_conquer(points, H, p_minx, p_maxx, buffered);
|
||||
#if USECONCVEC
|
||||
appendVector(H, hull);
|
||||
#else // STD::VECTOR
|
||||
hull.insert(hull.end(), H.begin(), H.end());
|
||||
#endif // USECONCVEC
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
utility::thread_number_range threads(utility::get_default_num_threads);
|
||||
util::ParseInputArgs(argc, argv, threads);
|
||||
|
||||
int nthreads;
|
||||
util::my_time_t tm_init, tm_start, tm_end;
|
||||
|
||||
#if USECONCVEC
|
||||
std::cout << "Starting TBB unbuffered push_back version of QUICK HULL algorithm" << std::endl;
|
||||
#else
|
||||
std::cout << "Starting STL locked unbuffered push_back version of QUICK HULL algorithm" << std::endl;
|
||||
#endif // USECONCVEC
|
||||
|
||||
for(nthreads=threads.first; nthreads<=threads.last; nthreads=threads.step(nthreads)) {
|
||||
pointVec_t points;
|
||||
pointVec_t hull;
|
||||
|
||||
tbb::global_control c(tbb::global_control::max_allowed_parallelism, nthreads);
|
||||
tm_init = util::gettime();
|
||||
initialize<FillRNDPointsVector>(points);
|
||||
tm_start = util::gettime();
|
||||
std::cout << "Parallel init time on " << nthreads << " threads: " << util::time_diff(tm_init, tm_start) << " Points in input: " << points.size() << "\n";
|
||||
|
||||
tm_start = util::gettime();
|
||||
quickhull(points, hull, false);
|
||||
tm_end = util::gettime();
|
||||
std::cout << "Time on " << nthreads << " threads: " << util::time_diff(tm_start, tm_end) << " Points in hull: " << hull.size() << "\n";
|
||||
}
|
||||
|
||||
#if USECONCVEC
|
||||
std::cout << "Starting TBB buffered version of QUICK HULL algorithm" << std::endl;
|
||||
#else
|
||||
std::cout << "Starting STL locked buffered version of QUICK HULL algorithm" << std::endl;
|
||||
#endif
|
||||
|
||||
for(nthreads=threads.first; nthreads<=threads.last; nthreads=threads.step(nthreads)) {
|
||||
pointVec_t points;
|
||||
pointVec_t hull;
|
||||
|
||||
tbb::global_control c(tbb::global_control::max_allowed_parallelism, nthreads);
|
||||
|
||||
tm_init = util::gettime();
|
||||
initialize<FillRNDPointsVector_buf>(points);
|
||||
tm_start = util::gettime();
|
||||
std::cout << "Init time on " << nthreads << " threads: " << util::time_diff(tm_init, tm_start) << " Points in input: " << points.size() << "\n";
|
||||
|
||||
tm_start = util::gettime();
|
||||
quickhull(points, hull, true);
|
||||
tm_end = util::gettime();
|
||||
std::cout << "Time on " << nthreads << " threads: " << util::time_diff(tm_start, tm_end) << " Points in hull: " << hull.size() << "\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // USETBB
|
||||
|
||||
void serial_initialize(pointVec_t &points) {
|
||||
points.reserve(cfg::numberOfPoints);
|
||||
|
||||
unsigned int rseed=1;
|
||||
for(size_t i=0, count=0; long(i)<cfg::numberOfPoints; ++i) {
|
||||
points.push_back(util::GenerateRNDPoint<double>(count,&std::rand,RAND_MAX ));
|
||||
}
|
||||
}
|
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file contains the TBB-based implementation of convex hull algortihm.
|
||||
It corresponds to the following settings in convex_hull_bench.cpp:
|
||||
- USETBB defined to 1
|
||||
- USECONCVEC defined to 1
|
||||
- INIT_ONCE defined to 0
|
||||
- only buffered version is used
|
||||
*/
|
||||
#include "convex_hull.h"
|
||||
|
||||
#include "tbb/parallel_for.h"
|
||||
#include "tbb/parallel_reduce.h"
|
||||
#include "tbb/blocked_range.h"
|
||||
#include "tbb/tick_count.h"
|
||||
#include "tbb/concurrent_vector.h"
|
||||
|
||||
typedef util::point<double> point_t;
|
||||
typedef tbb::concurrent_vector< point_t > pointVec_t;
|
||||
typedef tbb::blocked_range<size_t> range_t;
|
||||
|
||||
void appendVector(const point_t* src, size_t srcSize, pointVec_t& dest) {
|
||||
std::copy(src, src + srcSize, dest.grow_by(srcSize));
|
||||
}
|
||||
|
||||
void appendVector(const pointVec_t& src, pointVec_t& dest) {
|
||||
std::copy(src.begin(), src.end(), dest.grow_by(src.size()));
|
||||
}
|
||||
class FillRNDPointsVector_buf {
|
||||
pointVec_t &points;
|
||||
public:
|
||||
static const size_t grainSize = cfg::generateGrainSize;
|
||||
|
||||
explicit FillRNDPointsVector_buf(pointVec_t& _points)
|
||||
: points(_points) {}
|
||||
|
||||
void operator()(const range_t& range) const {
|
||||
util::rng the_rng(range.begin());
|
||||
const size_t i_end = range.end();
|
||||
size_t count = 0, j = 0;
|
||||
point_t tmp_vec[grainSize];
|
||||
|
||||
for(size_t i=range.begin(); i!=i_end; ++i) {
|
||||
tmp_vec[j++] = util::GenerateRNDPoint<double>(count, the_rng, util::rng::max_rand);
|
||||
}
|
||||
//Here we have race condition. Elements being written to may be still under construction.
|
||||
//For C++ 2003 it is workarounded by vector element type which default constructor does not touch memory,
|
||||
//it being constructed on. See comments near default ctor of point class for more details.
|
||||
//Strictly speaking it is UB.
|
||||
//TODO: need to find more reliable/correct way
|
||||
points.grow_to_at_least(range.end());
|
||||
std::copy(tmp_vec, tmp_vec+j,points.begin()+range.begin());
|
||||
}
|
||||
};
|
||||
|
||||
void initialize(pointVec_t &points) {
|
||||
//This function generate the same series of point on every call.
|
||||
//Reproducibility is needed for benchmarking to produce reliable results.
|
||||
//It is achieved through the following points:
|
||||
// - FillRNDPointsVector_buf instance has its own local instance
|
||||
// of random number generator, which in turn does not use any global data
|
||||
// - tbb::simple_partitioner produce the same set of ranges on every call to
|
||||
// tbb::parallel_for
|
||||
// - local RNG instances are seeded by the starting indexes of corresponding ranges
|
||||
// - grow_to_at_least() enables putting points into the resulting vector in deterministic order
|
||||
// (unlike concurrent push_back or grow_by).
|
||||
|
||||
// In the buffered version, a temporary storage for as much as grainSize elements
|
||||
// is allocated inside the body. Since auto_partitioner may increase effective
|
||||
// range size which would cause a crash, simple partitioner has to be used.
|
||||
tbb::parallel_for(range_t(0, cfg::numberOfPoints, FillRNDPointsVector_buf::grainSize),
|
||||
FillRNDPointsVector_buf(points), tbb::simple_partitioner());
|
||||
}
|
||||
|
||||
class FindXExtremum {
|
||||
public:
|
||||
typedef enum {
|
||||
minX, maxX
|
||||
} extremumType;
|
||||
|
||||
static const size_t grainSize = cfg::findExtremumGrainSize;
|
||||
|
||||
FindXExtremum(const pointVec_t& points_, extremumType exType_)
|
||||
: points(points_), exType(exType_), extrXPoint(points[0]) {}
|
||||
|
||||
FindXExtremum(const FindXExtremum& fxex, tbb::split)
|
||||
// Can run in parallel with fxex.operator()() or fxex.join().
|
||||
// The data race reported by tools is harmless.
|
||||
: points(fxex.points), exType(fxex.exType), extrXPoint(fxex.extrXPoint) {}
|
||||
|
||||
void operator()(const range_t& range) {
|
||||
const size_t i_end = range.end();
|
||||
if(!range.empty()) {
|
||||
for(size_t i = range.begin(); i != i_end; ++i) {
|
||||
if(closerToExtremum(points[i])) {
|
||||
extrXPoint = points[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void join(const FindXExtremum &rhs) {
|
||||
if(closerToExtremum(rhs.extrXPoint)) {
|
||||
extrXPoint = rhs.extrXPoint;
|
||||
}
|
||||
}
|
||||
|
||||
point_t extremeXPoint() {
|
||||
return extrXPoint;
|
||||
}
|
||||
|
||||
private:
|
||||
const pointVec_t &points;
|
||||
const extremumType exType;
|
||||
point_t extrXPoint;
|
||||
bool closerToExtremum(const point_t &p) const {
|
||||
switch(exType) {
|
||||
case minX:
|
||||
return p.x<extrXPoint.x; break;
|
||||
case maxX:
|
||||
return p.x>extrXPoint.x; break;
|
||||
}
|
||||
return false; // avoid warning
|
||||
}
|
||||
};
|
||||
|
||||
template <FindXExtremum::extremumType type>
|
||||
point_t extremum(const pointVec_t &P) {
|
||||
FindXExtremum fxBody(P, type);
|
||||
tbb::parallel_reduce(range_t(0, P.size(), FindXExtremum::grainSize), fxBody);
|
||||
return fxBody.extremeXPoint();
|
||||
}
|
||||
|
||||
class SplitByCP_buf {
|
||||
const pointVec_t &initialSet;
|
||||
pointVec_t &reducedSet;
|
||||
point_t p1, p2;
|
||||
point_t farPoint;
|
||||
double howFar;
|
||||
public:
|
||||
static const size_t grainSize = cfg::divideGrainSize;
|
||||
|
||||
SplitByCP_buf( point_t _p1, point_t _p2,
|
||||
const pointVec_t &_initialSet, pointVec_t &_reducedSet)
|
||||
: p1(_p1), p2(_p2),
|
||||
initialSet(_initialSet), reducedSet(_reducedSet),
|
||||
howFar(0), farPoint(p1) {}
|
||||
|
||||
SplitByCP_buf(SplitByCP_buf& sbcp, tbb::split)
|
||||
: p1(sbcp.p1), p2(sbcp.p2),
|
||||
initialSet(sbcp.initialSet), reducedSet(sbcp.reducedSet),
|
||||
howFar(0), farPoint(p1) {}
|
||||
|
||||
void operator()(const range_t& range) {
|
||||
const size_t i_end = range.end();
|
||||
size_t j = 0;
|
||||
double cp;
|
||||
point_t tmp_vec[grainSize];
|
||||
for(size_t i = range.begin(); i != i_end; ++i) {
|
||||
if( (initialSet[i] != p1) && (initialSet[i] != p2) ) {
|
||||
cp = util::cross_product(p1, p2, initialSet[i]);
|
||||
if(cp>0) {
|
||||
tmp_vec[j++] = initialSet[i];
|
||||
if(cp>howFar) {
|
||||
farPoint = initialSet[i];
|
||||
howFar = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appendVector(tmp_vec, j, reducedSet);
|
||||
}
|
||||
|
||||
void join(const SplitByCP_buf& rhs) {
|
||||
if(rhs.howFar>howFar) {
|
||||
howFar = rhs.howFar;
|
||||
farPoint = rhs.farPoint;
|
||||
}
|
||||
}
|
||||
|
||||
point_t farthestPoint() const {
|
||||
return farPoint;
|
||||
}
|
||||
};
|
||||
|
||||
point_t divide(const pointVec_t &P, pointVec_t &P_reduced,
|
||||
const point_t &p1, const point_t &p2) {
|
||||
SplitByCP_buf sbcpb(p1, p2, P, P_reduced);
|
||||
// Must use simple_partitioner (see the comment in initialize() above)
|
||||
tbb::parallel_reduce(range_t(0, P.size(), SplitByCP_buf::grainSize),
|
||||
sbcpb, tbb::simple_partitioner());
|
||||
|
||||
if(util::verbose) {
|
||||
std::stringstream ss;
|
||||
ss << P.size() << " nodes in bucket"<< ", "
|
||||
<< "dividing by: [ " << p1 << ", " << p2 << " ], "
|
||||
<< "farthest node: " << sbcpb.farthestPoint();
|
||||
util::OUTPUT.push_back(ss.str());
|
||||
}
|
||||
|
||||
return sbcpb.farthestPoint();
|
||||
}
|
||||
|
||||
void divide_and_conquer(const pointVec_t &P, pointVec_t &H,
|
||||
point_t p1, point_t p2) {
|
||||
assert(P.size() >= 2);
|
||||
pointVec_t P_reduced;
|
||||
pointVec_t H1, H2;
|
||||
point_t p_far = divide(P, P_reduced, p1, p2);
|
||||
if (P_reduced.size()<2) {
|
||||
H.push_back(p1);
|
||||
appendVector(P_reduced, H);
|
||||
}
|
||||
else {
|
||||
divide_and_conquer(P_reduced, H1, p1, p_far);
|
||||
divide_and_conquer(P_reduced, H2, p_far, p2);
|
||||
|
||||
appendVector(H1, H);
|
||||
appendVector(H2, H);
|
||||
}
|
||||
}
|
||||
|
||||
void quickhull(const pointVec_t &points, pointVec_t &hull) {
|
||||
if (points.size() < 2) {
|
||||
appendVector(points, hull);
|
||||
return;
|
||||
}
|
||||
|
||||
point_t p_maxx = extremum<FindXExtremum::maxX>(points);
|
||||
point_t p_minx = extremum<FindXExtremum::minX>(points);
|
||||
|
||||
pointVec_t H;
|
||||
|
||||
divide_and_conquer(points, hull, p_maxx, p_minx);
|
||||
divide_and_conquer(points, H, p_minx, p_maxx);
|
||||
|
||||
appendVector(H, hull);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
utility::thread_number_range threads(utility::get_default_num_threads);
|
||||
util::my_time_t tm_main_begin = util::gettime();
|
||||
|
||||
util::ParseInputArgs(argc, argv, threads);
|
||||
|
||||
pointVec_t points;
|
||||
pointVec_t hull;
|
||||
int nthreads;
|
||||
|
||||
points.reserve(cfg::numberOfPoints);
|
||||
|
||||
if(!util::silent) {
|
||||
std::cout << "Starting TBB-buffered version of QUICK HULL algorithm" << std::endl;
|
||||
}
|
||||
|
||||
for(nthreads=threads.first; nthreads<=threads.last; nthreads=threads.step(nthreads)) {
|
||||
tbb::global_control c(tbb::global_control::max_allowed_parallelism, nthreads);
|
||||
|
||||
points.clear();
|
||||
util::my_time_t tm_init = util::gettime();
|
||||
initialize(points);
|
||||
util::my_time_t tm_start = util::gettime();
|
||||
if(!util::silent) {
|
||||
std::cout <<"Init time on "<<nthreads<<" threads: "<<util::time_diff(tm_init, tm_start)<<" Points in input: "<<points.size()<<std::endl;
|
||||
}
|
||||
|
||||
tm_start = util::gettime();
|
||||
quickhull(points, hull);
|
||||
util::my_time_t tm_end = util::gettime();
|
||||
if(!util::silent) {
|
||||
std::cout <<"Time on "<<nthreads<<" threads: "<<util::time_diff(tm_start, tm_end)<<" Points in hull: "<<hull.size()<<std::endl;
|
||||
}
|
||||
hull.clear();
|
||||
}
|
||||
utility::report_elapsed_time(util::time_diff(tm_main_begin, util::gettime()));
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,400 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
::selection {
|
||||
background: #b7ffb7;
|
||||
}
|
||||
::-moz-selection {
|
||||
background: #b7ffb7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#banner {
|
||||
/* Div for banner */
|
||||
float:left;
|
||||
margin: 0px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
background-color: #0071C5;
|
||||
z-index: 0;
|
||||
}
|
||||
#banner .logo {
|
||||
/* Apply to logo in banner. Add as class to image tag. */
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
margin-top: 15px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 36px;
|
||||
}
|
||||
h1.title {
|
||||
/* Add as class to H1 in banner */
|
||||
font-family: "Intel Clear", Verdana, Arial, sans-serif;
|
||||
font-weight:normal;
|
||||
color: #FFFFFF;
|
||||
font-size: 170%;
|
||||
margin-right: 40px;
|
||||
margin-left: 40px;
|
||||
padding-right: 20px;
|
||||
text-indent: 20px;
|
||||
}
|
||||
.h3-alike {
|
||||
display:inline;
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
color: #0071C5;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
color: #0071C5;
|
||||
}
|
||||
.h4-alike {
|
||||
display:inline;
|
||||
font-size: 1.05em;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
font-family: "Consolas", Monaco, monospace;
|
||||
font-size:small;
|
||||
background: #fafafa;
|
||||
margin: 0;
|
||||
padding-left:20px;
|
||||
}
|
||||
#footer {
|
||||
font-size: small;
|
||||
}
|
||||
code {
|
||||
font-family: "Consolas", Monaco, monospace;
|
||||
}
|
||||
.code-block
|
||||
{
|
||||
padding-left:20px;
|
||||
}
|
||||
.changes {
|
||||
margin: 1em 0;
|
||||
}
|
||||
.changes input:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.changes input:hover:after {
|
||||
padding-left: 16px;
|
||||
font-size: 10px;
|
||||
content: 'More';
|
||||
}
|
||||
.changes input:checked:hover:after {
|
||||
content: 'Less';
|
||||
}
|
||||
.changes input + .show-hide {
|
||||
display: none;
|
||||
}
|
||||
.changes input:checked + .show-hide {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
}
|
||||
ul li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
ul li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.disc {
|
||||
list-style-type:disc
|
||||
}
|
||||
.circ {
|
||||
list-style-type:circle
|
||||
}
|
||||
|
||||
.single {
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* Table styles */
|
||||
table{
|
||||
margin-bottom:5pt;
|
||||
border-collapse:collapse;
|
||||
margin-left:0px;
|
||||
margin-top:0.3em;
|
||||
font-size:10pt;
|
||||
}
|
||||
tr{
|
||||
vertical-align:top;
|
||||
}
|
||||
th,
|
||||
th h3{
|
||||
padding:4px;
|
||||
text-align:left;
|
||||
background-color:#0071C5;
|
||||
font-weight:bold;
|
||||
margin-top:1px;
|
||||
margin-bottom:0;
|
||||
color:#FFFFFF;
|
||||
font-size:10pt;
|
||||
vertical-align:middle;
|
||||
}
|
||||
th{
|
||||
border:1px #dddddd solid;
|
||||
padding-top:2px;
|
||||
padding-bottom:0px;
|
||||
padding-right:3px;
|
||||
padding-left:3px;
|
||||
}
|
||||
td{
|
||||
border:1px #dddddd solid;
|
||||
vertical-align:top;
|
||||
font-size:100%;
|
||||
text-align:left;
|
||||
margin-bottom:0;
|
||||
}
|
||||
td,
|
||||
td p{
|
||||
margin-top:0;
|
||||
margin-left:0;
|
||||
text-align:left;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
}
|
||||
td p{
|
||||
margin-bottom:0;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
padding-right:5px;
|
||||
padding-left:1px;
|
||||
}
|
||||
.noborder{
|
||||
border:0px none;
|
||||
}
|
||||
.noborder1stcol{
|
||||
border:0px none;
|
||||
padding-left:0pt;
|
||||
}
|
||||
td ol{
|
||||
font-size:inherit;
|
||||
margin-left:28px;
|
||||
}
|
||||
td ul{
|
||||
font-size:inherit;
|
||||
margin-left:24px;
|
||||
}
|
||||
.DefListTbl{
|
||||
width:90%;
|
||||
margin-left:-3pt;
|
||||
}
|
||||
.syntaxdiagramtbl{
|
||||
margin-left:-3pt;
|
||||
}
|
||||
.sdtbl{
|
||||
}
|
||||
.sdrow{
|
||||
}
|
||||
.sdtblp{
|
||||
border:0px none;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
margin-bottom:0;
|
||||
padding-bottom:0px;
|
||||
padding-top:5px;
|
||||
padding-left:0px;
|
||||
padding-right:5px;
|
||||
vertical-align:top;
|
||||
}
|
||||
.idepara, .ide_para{
|
||||
border:0px none;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
margin-bottom:0;
|
||||
padding-bottom:0px;
|
||||
padding-top:5px;
|
||||
padding-left:0px;
|
||||
padding-right:5px;
|
||||
vertical-align:top;
|
||||
}
|
||||
|
||||
.specs {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
.specs td, .specs th {
|
||||
font-size: 14px;
|
||||
}
|
||||
.specs td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
.specs td td, .specs td th {
|
||||
border: none;
|
||||
}
|
||||
.specs td, .specs td td, .specs td th {
|
||||
padding: 0 0.2em 0.2em;
|
||||
text-align: center;
|
||||
}
|
||||
.specs td tr:last-child td,
|
||||
.specs td tr:last-child th {
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
.serial-time {
|
||||
}
|
||||
.modified-time {
|
||||
width: 6.5em;
|
||||
}
|
||||
.compiler {
|
||||
}
|
||||
.comp-opt {
|
||||
}
|
||||
.sys-specs {
|
||||
width: 18em;
|
||||
}
|
||||
.note {
|
||||
font-size:small;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
<title>Intel® Threading Building Blocks. Convex_hull sample</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="banner">
|
||||
<img class="logo" src="data:image/png;base64,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
|
||||
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
|
||||
<h1 class="title">Intel® Threading Building Blocks.<br>Convex_hull sample</h1>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Parallel version of convex hull algorithm (quick hull).
|
||||
</p>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">System Requirements</div>
|
||||
<input type="checkbox">
|
||||
<div class="show-hide">
|
||||
<p>
|
||||
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Files</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><a href="convex_hull_sample.cpp">convex_hull_sample.cpp</a>
|
||||
<dd>Source code for parallel version of the example which uses parallel_reduce, parallel_for and concurrent_vector.
|
||||
<dt><a href="convex_hull_bench.cpp">convex_hull_bench.cpp</a>
|
||||
<dd>Source code for the version of the example that compares serial and parallel buffered and unbuffered implementations.
|
||||
<dt><a href="convex_hull.h">convex_hull.h</a>
|
||||
<dd>Include file for the example.
|
||||
<dt><a href="Makefile">Makefile</a>
|
||||
<dd>Makefile for building the example.
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Directories</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><a href="msvs/">msvs</a>
|
||||
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
|
||||
<dt><a href="xcode/">xcode</a>
|
||||
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
|
||||
</dl>
|
||||
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Build instructions</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Usage</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><tt>convex_hull_sample [<i>S</i>] [<i>M</i>[:<i>N</i>]] [-v]</tt>
|
||||
<dd><i>S</i> is the number of points (problem size).
|
||||
<i>M:N</i> are a range of numbers of threads to be used.
|
||||
Use the -v option to turn on verbose output.
|
||||
<dt>To run a short version of this example, e.g., for use with Intel® Threading Tools:
|
||||
<dd>Build a <i>debug</i> version of the example
|
||||
(see the <a href="../../index.html">build instructions</a>).
|
||||
<br>Run it with a small problem size and the desired number of threads, e.g., <tt>convex_hull_sample 4 500000</tt>.
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<a href="../index.html">Up to parent directory</a>
|
||||
<hr>
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Legal Information</div>
|
||||
<input type="checkbox">
|
||||
<div class="show-hide">
|
||||
<p>
|
||||
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
|
||||
<br>* Other names and brands may be claimed as the property of others.
|
||||
<br>© 2020, Intel Corporation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -0,0 +1,350 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A146114A0B94631F000C6B18 /* convex_hull_bench.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14611490B94631F000C6B18 /* convex_hull_bench.cpp */; };
|
||||
A1F593A60B8F042A00073279 /* convex_hull_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* convex_hull_sample.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildRule section */
|
||||
C3C5895A218B677B00DAC94C /* PBXBuildRule */ = {
|
||||
isa = PBXBuildRule;
|
||||
compilerSpec = com.intel.compilers.icc.latest;
|
||||
fileType = sourcecode.cpp;
|
||||
isEditable = 1;
|
||||
outputFiles = (
|
||||
);
|
||||
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
|
||||
};
|
||||
/* End PBXBuildRule section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 12;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1F594F40B8F4E7700073279 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A14611490B94631F000C6B18 /* convex_hull_bench.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = convex_hull_bench.cpp; path = ../convex_hull_bench.cpp; sourceTree = SOURCE_ROOT; };
|
||||
A146114C0B9463CB000C6B18 /* convex_hull.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = convex_hull.h; path = ../convex_hull.h; sourceTree = SOURCE_ROOT; };
|
||||
A1F593A50B8F042A00073279 /* convex_hull_sample.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = convex_hull_sample.cpp; path = ../convex_hull_sample.cpp; sourceTree = SOURCE_ROOT; };
|
||||
A1F594EB0B8F4B5600073279 /* convex_hull_bench */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = convex_hull_bench; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1F594FA0B8F4EE000073279 /* convex_hull_sample */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = convex_hull_sample; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8DD76F660486A84900D96B5E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1F594E90B8F4B5600073279 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
08FB7794FE84155DC02AAC07 /* convex_hull */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
);
|
||||
name = convex_hull;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7795FE84155DC02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A146114C0B9463CB000C6B18 /* convex_hull.h */,
|
||||
A14611490B94631F000C6B18 /* convex_hull_bench.cpp */,
|
||||
A1F593A50B8F042A00073279 /* convex_hull_sample.cpp */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1F594EB0B8F4B5600073279 /* convex_hull_bench */,
|
||||
A1F594FA0B8F4EE000073279 /* convex_hull_sample */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8DD76F620486A84900D96B5E /* convex_hull_sample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "convex_hull_sample" */;
|
||||
buildPhases = (
|
||||
8DD76F640486A84900D96B5E /* Sources */,
|
||||
8DD76F660486A84900D96B5E /* Frameworks */,
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
C3C5895A218B677B00DAC94C /* PBXBuildRule */,
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = convex_hull_sample;
|
||||
productInstallPath = "$(HOME)/bin";
|
||||
productName = convex_hull;
|
||||
productReference = A1F594FA0B8F4EE000073279 /* convex_hull_sample */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
A1F594EA0B8F4B5600073279 /* convex_hull_bench */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1F594EE0B8F4B8200073279 /* Build configuration list for PBXNativeTarget "convex_hull_bench" */;
|
||||
buildPhases = (
|
||||
A1F594E80B8F4B5600073279 /* Sources */,
|
||||
A1F594E90B8F4B5600073279 /* Frameworks */,
|
||||
A1F594F40B8F4E7700073279 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = convex_hull_bench;
|
||||
productName = convex_hull_bench;
|
||||
productReference = A1F594EB0B8F4B5600073279 /* convex_hull_bench */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1000;
|
||||
};
|
||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "convex_hull" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* convex_hull */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8DD76F620486A84900D96B5E /* convex_hull_sample */,
|
||||
A1F594EA0B8F4B5600073279 /* convex_hull_bench */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8DD76F640486A84900D96B5E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1F593A60B8F042A00073279 /* convex_hull_sample.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1F594E80B8F4B5600073279 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A146114A0B94631F000C6B18 /* convex_hull_bench.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
PRODUCT_NAME = convex_hull_sample;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Debug64;
|
||||
};
|
||||
A1F593C70B8F0E6E00073279 /* Release64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_VERSION = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
PRODUCT_NAME = convex_hull_sample;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release64;
|
||||
};
|
||||
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_ENABLE_CPP_RTTI = YES;
|
||||
GCC_MODEL_TUNING = "";
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/include",
|
||||
/opt/intel/tbb/include,
|
||||
);
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/lib",
|
||||
/opt/intel/tbb/lib,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-m64",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-m64",
|
||||
"-ltbb_debug",
|
||||
);
|
||||
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
|
||||
SYMROOT = "/tmp/tbb-$(USER)";
|
||||
VALID_ARCHS = x86_64;
|
||||
};
|
||||
name = Debug64;
|
||||
};
|
||||
A1F593C90B8F0E6E00073279 /* Release64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = YES;
|
||||
GCC_MODEL_TUNING = "";
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/include",
|
||||
/opt/intel/tbb/include,
|
||||
);
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/lib",
|
||||
/opt/intel/tbb/lib,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-m64",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-m64",
|
||||
"-ltbb",
|
||||
);
|
||||
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
|
||||
SYMROOT = "/tmp/tbb-$(USER)";
|
||||
VALID_ARCHS = x86_64;
|
||||
};
|
||||
name = Release64;
|
||||
};
|
||||
A1F594F00B8F4B8200073279 /* Debug64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
PRODUCT_NAME = convex_hull_bench;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Debug64;
|
||||
};
|
||||
A1F594F20B8F4B8200073279 /* Release64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_VERSION = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
PRODUCT_NAME = convex_hull_bench;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release64;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "convex_hull_sample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1F593C60B8F0E6E00073279 /* Debug64 */,
|
||||
A1F593C70B8F0E6E00073279 /* Release64 */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release64;
|
||||
};
|
||||
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "convex_hull" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1F593C80B8F0E6E00073279 /* Debug64 */,
|
||||
A1F593C90B8F0E6E00073279 /* Release64 */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release64;
|
||||
};
|
||||
A1F594EE0B8F4B8200073279 /* Build configuration list for PBXNativeTarget "convex_hull_bench" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1F594F00B8F4B8200073279 /* Debug64 */,
|
||||
A1F594F20B8F4B8200073279 /* Release64 */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release64;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
}
|
346
cs440-acg/ext/tbb/examples/parallel_reduce/index.html
Normal file
346
cs440-acg/ext/tbb/examples/parallel_reduce/index.html
Normal file
@@ -0,0 +1,346 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
::selection {
|
||||
background: #b7ffb7;
|
||||
}
|
||||
::-moz-selection {
|
||||
background: #b7ffb7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#banner {
|
||||
/* Div for banner */
|
||||
float:left;
|
||||
margin: 0px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
background-color: #0071C5;
|
||||
z-index: 0;
|
||||
}
|
||||
#banner .logo {
|
||||
/* Apply to logo in banner. Add as class to image tag. */
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
margin-top: 15px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 36px;
|
||||
}
|
||||
h1.title {
|
||||
/* Add as class to H1 in banner */
|
||||
font-family: "Intel Clear", Verdana, Arial, sans-serif;
|
||||
font-weight:normal;
|
||||
color: #FFFFFF;
|
||||
font-size: 170%;
|
||||
margin-right: 40px;
|
||||
margin-left: 40px;
|
||||
padding-right: 20px;
|
||||
text-indent: 20px;
|
||||
}
|
||||
.h3-alike {
|
||||
display:inline;
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
color: #0071C5;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
color: #0071C5;
|
||||
}
|
||||
.h4-alike {
|
||||
display:inline;
|
||||
font-size: 1.05em;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
font-family: "Consolas", Monaco, monospace;
|
||||
font-size:small;
|
||||
background: #fafafa;
|
||||
margin: 0;
|
||||
padding-left:20px;
|
||||
}
|
||||
#footer {
|
||||
font-size: small;
|
||||
}
|
||||
code {
|
||||
font-family: "Consolas", Monaco, monospace;
|
||||
}
|
||||
.code-block
|
||||
{
|
||||
padding-left:20px;
|
||||
}
|
||||
.changes {
|
||||
margin: 1em 0;
|
||||
}
|
||||
.changes input:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.changes input:hover:after {
|
||||
padding-left: 16px;
|
||||
font-size: 10px;
|
||||
content: 'More';
|
||||
}
|
||||
.changes input:checked:hover:after {
|
||||
content: 'Less';
|
||||
}
|
||||
.changes input + .show-hide {
|
||||
display: none;
|
||||
}
|
||||
.changes input:checked + .show-hide {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
}
|
||||
ul li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
ul li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.disc {
|
||||
list-style-type:disc
|
||||
}
|
||||
.circ {
|
||||
list-style-type:circle
|
||||
}
|
||||
|
||||
.single {
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* Table styles */
|
||||
table{
|
||||
margin-bottom:5pt;
|
||||
border-collapse:collapse;
|
||||
margin-left:0px;
|
||||
margin-top:0.3em;
|
||||
font-size:10pt;
|
||||
}
|
||||
tr{
|
||||
vertical-align:top;
|
||||
}
|
||||
th,
|
||||
th h3{
|
||||
padding:4px;
|
||||
text-align:left;
|
||||
background-color:#0071C5;
|
||||
font-weight:bold;
|
||||
margin-top:1px;
|
||||
margin-bottom:0;
|
||||
color:#FFFFFF;
|
||||
font-size:10pt;
|
||||
vertical-align:middle;
|
||||
}
|
||||
th{
|
||||
border:1px #dddddd solid;
|
||||
padding-top:2px;
|
||||
padding-bottom:0px;
|
||||
padding-right:3px;
|
||||
padding-left:3px;
|
||||
}
|
||||
td{
|
||||
border:1px #dddddd solid;
|
||||
vertical-align:top;
|
||||
font-size:100%;
|
||||
text-align:left;
|
||||
margin-bottom:0;
|
||||
}
|
||||
td,
|
||||
td p{
|
||||
margin-top:0;
|
||||
margin-left:0;
|
||||
text-align:left;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
}
|
||||
td p{
|
||||
margin-bottom:0;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
padding-right:5px;
|
||||
padding-left:1px;
|
||||
}
|
||||
.noborder{
|
||||
border:0px none;
|
||||
}
|
||||
.noborder1stcol{
|
||||
border:0px none;
|
||||
padding-left:0pt;
|
||||
}
|
||||
td ol{
|
||||
font-size:inherit;
|
||||
margin-left:28px;
|
||||
}
|
||||
td ul{
|
||||
font-size:inherit;
|
||||
margin-left:24px;
|
||||
}
|
||||
.DefListTbl{
|
||||
width:90%;
|
||||
margin-left:-3pt;
|
||||
}
|
||||
.syntaxdiagramtbl{
|
||||
margin-left:-3pt;
|
||||
}
|
||||
.sdtbl{
|
||||
}
|
||||
.sdrow{
|
||||
}
|
||||
.sdtblp{
|
||||
border:0px none;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
margin-bottom:0;
|
||||
padding-bottom:0px;
|
||||
padding-top:5px;
|
||||
padding-left:0px;
|
||||
padding-right:5px;
|
||||
vertical-align:top;
|
||||
}
|
||||
.idepara, .ide_para{
|
||||
border:0px none;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
margin-bottom:0;
|
||||
padding-bottom:0px;
|
||||
padding-top:5px;
|
||||
padding-left:0px;
|
||||
padding-right:5px;
|
||||
vertical-align:top;
|
||||
}
|
||||
|
||||
.specs {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
.specs td, .specs th {
|
||||
font-size: 14px;
|
||||
}
|
||||
.specs td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
.specs td td, .specs td th {
|
||||
border: none;
|
||||
}
|
||||
.specs td, .specs td td, .specs td th {
|
||||
padding: 0 0.2em 0.2em;
|
||||
text-align: center;
|
||||
}
|
||||
.specs td tr:last-child td,
|
||||
.specs td tr:last-child th {
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
.serial-time {
|
||||
}
|
||||
.modified-time {
|
||||
width: 6.5em;
|
||||
}
|
||||
.compiler {
|
||||
}
|
||||
.comp-opt {
|
||||
}
|
||||
.sys-specs {
|
||||
width: 18em;
|
||||
}
|
||||
.note {
|
||||
font-size:small;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
<title>Intel® Threading Building Blocks. Samples on parallel_reduce</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="banner">
|
||||
<img class="logo" src="data:image/png;base64,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
|
||||
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
|
||||
<h1 class="title">Intel® Threading Building Blocks.<br>Samples on <code>parallel_reduce</code> algorithm</h1>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This directory has examples of the <code>parallel_reduce</code> algorithm.
|
||||
</p>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Directories</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><a href="convex_hull/readme.html">convex_hull</a>
|
||||
<dd>Parallel version of convex hull algorithm (quick hull).
|
||||
<dt><a href="primes/readme.html">primes</a>
|
||||
<dd>Parallel version of the Sieve of Eratosthenes.
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<a href="../index.html">Up to parent directory</a>
|
||||
<hr>
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Legal Information:</div>
|
||||
<input type="checkbox">
|
||||
<div class="show-hide">
|
||||
<p>
|
||||
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
|
||||
<br>* Other names and brands may be claimed as the property of others.
|
||||
<br>© 2020, Intel Corporation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -0,0 +1,48 @@
|
||||
# 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.
|
||||
|
||||
# Common Makefile that builds and runs example.
|
||||
|
||||
# Just specify your program basename
|
||||
PROG=Primes
|
||||
ARGS=0:auto
|
||||
PERF_RUN_ARGS=silent auto 1000000000 1000 20
|
||||
|
||||
# Trying to find if icl.exe is set
|
||||
CXX1 = $(TBB_CXX)-
|
||||
CXX2 = $(CXX1:icl.exe-=icl.exe)
|
||||
CXX = $(CXX2:-=cl.exe)
|
||||
|
||||
# The C++ compiler options
|
||||
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 $(CXXFLAGS)
|
||||
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
|
||||
|
||||
all: release test
|
||||
release: compiler_check
|
||||
$(CXX) main.cpp primes.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
|
||||
debug: compiler_check
|
||||
$(CXX) main.cpp primes.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
|
||||
clean:
|
||||
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
|
||||
test:
|
||||
$(PROG) $(ARGS)
|
||||
|
||||
perf_build: release
|
||||
|
||||
perf_run:
|
||||
$(PROG) $(PERF_RUN_ARGS)
|
||||
|
||||
compiler_check:
|
||||
@echo compiler_test>compiler_test && @$(CXX) /E compiler_test >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
|
||||
@cmd.exe /C del compiler_test
|
106
cs440-acg/ext/tbb/examples/parallel_reduce/primes/main.cpp
Normal file
106
cs440-acg/ext/tbb/examples/parallel_reduce/primes/main.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
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 "primes.h"
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "tbb/tick_count.h"
|
||||
|
||||
#include "../../common/utility/utility.h"
|
||||
|
||||
struct RunOptions{
|
||||
//! NumberType of threads to use.
|
||||
utility::thread_number_range threads;
|
||||
//whether to suppress additional output
|
||||
bool silentFlag;
|
||||
//
|
||||
NumberType n;
|
||||
//! Grain size parameter
|
||||
NumberType grainSize;
|
||||
// number of time to repeat calculation
|
||||
NumberType repeatNumber;
|
||||
|
||||
RunOptions(utility::thread_number_range threads_, NumberType grainSize_, NumberType n_, bool silentFlag_, NumberType repeatNumber_)
|
||||
: threads(threads_), silentFlag(silentFlag_), n(n_), grainSize(grainSize_), repeatNumber(repeatNumber_)
|
||||
{}
|
||||
};
|
||||
|
||||
//! Parse the command line.
|
||||
static RunOptions ParseCommandLine( int argc, const char* argv[] ) {
|
||||
utility::thread_number_range threads( utility::get_default_num_threads, 0, utility::get_default_num_threads() );
|
||||
NumberType grainSize = 1000;
|
||||
bool silent = false;
|
||||
NumberType number = 100000000;
|
||||
NumberType repeatNumber = 1;
|
||||
|
||||
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,"number","upper bound of range to search primes in, must be a positive integer")
|
||||
.positional_arg(grainSize,"grain-size","must be a positive integer")
|
||||
.positional_arg(repeatNumber,"n-of-repeats","repeat the calculation this number of times, must be a positive integer")
|
||||
.arg(silent,"silent","no output except elapsed time")
|
||||
);
|
||||
|
||||
RunOptions options(threads,grainSize, number, silent, repeatNumber);
|
||||
return options;
|
||||
}
|
||||
|
||||
int main( int argc, const char* argv[] ) {
|
||||
tbb::tick_count mainBeginMark = tbb::tick_count::now();
|
||||
RunOptions options =ParseCommandLine(argc,argv);
|
||||
|
||||
// Try different numbers of threads
|
||||
for( int p=options.threads.first; p<=options.threads.last; p=options.threads.step(p) ) {
|
||||
for (NumberType i=0; i<options.repeatNumber;++i){
|
||||
tbb::tick_count iterationBeginMark = tbb::tick_count::now();
|
||||
NumberType count = 0;
|
||||
NumberType n = options.n;
|
||||
if( p==0 ) {
|
||||
#if __TBB_MIC_OFFLOAD
|
||||
#pragma offload target(mic) in(n) out(count)
|
||||
#endif // __TBB_MIC_OFFLOAD
|
||||
count = SerialCountPrimes(n);
|
||||
} else {
|
||||
NumberType grainSize = options.grainSize;
|
||||
#if __TBB_MIC_OFFLOAD
|
||||
#pragma offload target(mic) in(n, p, grainSize) out(count)
|
||||
#endif // __TBB_MIC_OFFLOAD
|
||||
count = ParallelCountPrimes(n, p, grainSize);
|
||||
}
|
||||
tbb::tick_count iterationEndMark = tbb::tick_count::now();
|
||||
if (!options.silentFlag){
|
||||
std::cout
|
||||
<<"#primes from [2.." <<options.n<<"] = " << count
|
||||
<<" ("<<(iterationEndMark-iterationBeginMark).seconds()<< " sec with "
|
||||
;
|
||||
if( 0 != p )
|
||||
std::cout<<p<<"-way parallelism";
|
||||
else
|
||||
std::cout<<"serial code";
|
||||
std::cout<<")\n" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
utility::report_elapsed_time((tbb::tick_count::now()-mainBeginMark).seconds());
|
||||
return 0;
|
||||
}
|
304
cs440-acg/ext/tbb/examples/parallel_reduce/primes/primes.cpp
Normal file
304
cs440-acg/ext/tbb/examples/parallel_reduce/primes/primes.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// Example program that computes number of prime numbers up to n,
|
||||
// where n is a command line argument. The algorithm here is a
|
||||
// fairly efficient version of the sieve of Eratosthenes.
|
||||
// The parallel version demonstrates how to use parallel_reduce,
|
||||
// and in particular how to exploit lazy splitting.
|
||||
|
||||
#include "primes.h"
|
||||
|
||||
#if __TBB_MIC_OFFLOAD
|
||||
#pragma offload_attribute (target(mic))
|
||||
#endif // __TBB_MIC_OFFLOAD
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <math.h>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include "tbb/parallel_reduce.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//! If true, then print primes on stdout.
|
||||
static bool printPrimes = false;
|
||||
|
||||
|
||||
class Multiples {
|
||||
inline NumberType strike( NumberType start, NumberType limit, NumberType stride ) {
|
||||
// Hoist "my_is_composite" into register for sake of speed.
|
||||
bool* is_composite = my_is_composite;
|
||||
assert( stride>=2 );
|
||||
for( ;start<limit; start+=stride )
|
||||
is_composite[start] = true;
|
||||
return start;
|
||||
}
|
||||
//! Window into conceptual sieve
|
||||
bool* my_is_composite;
|
||||
|
||||
//! Indexes into window
|
||||
/** my_striker[k] is an index into my_composite corresponding to
|
||||
an odd multiple multiple of my_factor[k]. */
|
||||
NumberType* my_striker;
|
||||
|
||||
//! Prime numbers less than m.
|
||||
NumberType* my_factor;
|
||||
public:
|
||||
//! NumberType of factors in my_factor.
|
||||
NumberType n_factor;
|
||||
NumberType m;
|
||||
Multiples( NumberType n ) {
|
||||
m = NumberType(sqrt(double(n)));
|
||||
// Round up to even
|
||||
m += m&1;
|
||||
my_is_composite = new bool[m/2];
|
||||
my_striker = new NumberType[m/2];
|
||||
my_factor = new NumberType[m/2];
|
||||
n_factor = 0;
|
||||
memset( my_is_composite, 0, m/2 );
|
||||
for( NumberType i=3; i<m; i+=2 ) {
|
||||
if( !my_is_composite[i/2] ) {
|
||||
if( printPrimes )
|
||||
printf("%d\n",(int)i);
|
||||
my_striker[n_factor] = strike( i/2, m/2, i );
|
||||
my_factor[n_factor++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Find primes in range [start,window_size), advancing my_striker as we go.
|
||||
/** Returns number of primes found. */
|
||||
NumberType find_primes_in_window( NumberType start, NumberType window_size ) {
|
||||
bool* is_composite = my_is_composite;
|
||||
memset( is_composite, 0, window_size/2 );
|
||||
for( size_t k=0; k<n_factor; ++k )
|
||||
my_striker[k] = strike( my_striker[k]-m/2, window_size/2, my_factor[k] );
|
||||
NumberType count = 0;
|
||||
for( NumberType k=0; k<window_size/2; ++k ) {
|
||||
if( !is_composite[k] ) {
|
||||
if( printPrimes )
|
||||
printf("%ld\n",long(start+2*k+1));
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
~Multiples() {
|
||||
delete[] my_factor;
|
||||
delete[] my_striker;
|
||||
delete[] my_is_composite;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Begin extra members required by parallel version
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Splitting constructor
|
||||
Multiples( const Multiples& f, tbb::split ) :
|
||||
n_factor(f.n_factor),
|
||||
m(f.m),
|
||||
my_is_composite(NULL),
|
||||
my_striker(NULL),
|
||||
my_factor(f.my_factor)
|
||||
{}
|
||||
|
||||
bool is_initialized() const {
|
||||
return my_is_composite!=NULL;
|
||||
}
|
||||
|
||||
void initialize( NumberType start ) {
|
||||
assert( start>=1 );
|
||||
my_is_composite = new bool[m/2];
|
||||
my_striker = new NumberType[m/2];
|
||||
for( size_t k=0; k<n_factor; ++k ) {
|
||||
NumberType f = my_factor[k];
|
||||
NumberType p = (start-1)/f*f % m;
|
||||
my_striker[k] = (p&1 ? p+2*f : p+f)/2;
|
||||
assert( m/2<=my_striker[k] );
|
||||
}
|
||||
}
|
||||
|
||||
// Move other to *this.
|
||||
void move( Multiples& other ) {
|
||||
// The swap moves the contents of other to *this and causes the old contents
|
||||
// of *this to be deleted later when other is destroyed.
|
||||
std::swap( my_striker, other.my_striker );
|
||||
std::swap( my_is_composite, other.my_is_composite );
|
||||
// other.my_factor is a shared pointer that was copied by the splitting constructor.
|
||||
// Set it to NULL to prevent premature deletion by the destructor of ~other.
|
||||
assert(my_factor==other.my_factor);
|
||||
other.my_factor = NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// End extra methods required by parallel version
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//! Count number of primes between 0 and n
|
||||
/** This is the serial version. */
|
||||
NumberType SerialCountPrimes( NumberType n ) {
|
||||
// Two is special case
|
||||
NumberType count = n>=2;
|
||||
if( n>=3 ) {
|
||||
Multiples multiples(n);
|
||||
count += multiples.n_factor;
|
||||
if( printPrimes )
|
||||
printf("---\n");
|
||||
NumberType window_size = multiples.m;
|
||||
for( NumberType j=multiples.m; j<=n; j+=window_size ) {
|
||||
if( j+window_size>n+1 )
|
||||
window_size = n+1-j;
|
||||
count += multiples.find_primes_in_window( j, window_size );
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//! Range of a sieve window.
|
||||
class SieveRange {
|
||||
//! Width of full-size window into sieve.
|
||||
const NumberType my_stride;
|
||||
|
||||
//! Always multiple of my_stride
|
||||
NumberType my_begin;
|
||||
|
||||
//! One past last number in window.
|
||||
NumberType my_end;
|
||||
|
||||
//! Width above which it is worth forking.
|
||||
const NumberType my_grainsize;
|
||||
|
||||
bool assert_okay() const {
|
||||
assert( my_begin%my_stride==0 );
|
||||
assert( my_begin<=my_end );
|
||||
assert( my_stride<=my_grainsize );
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
// Begin signatures required by parallel_reduce
|
||||
//------------------------------------------------------------------------
|
||||
bool is_divisible() const {return my_end-my_begin>my_grainsize;}
|
||||
bool empty() const {return my_end<=my_begin;}
|
||||
SieveRange( SieveRange& r, tbb::split ) :
|
||||
my_stride(r.my_stride),
|
||||
my_grainsize(r.my_grainsize),
|
||||
my_end(r.my_end)
|
||||
{
|
||||
assert( r.is_divisible() );
|
||||
assert( r.assert_okay() );
|
||||
NumberType middle = r.my_begin + (r.my_end-r.my_begin+r.my_stride-1)/2;
|
||||
middle = middle/my_stride*my_stride;
|
||||
my_begin = middle;
|
||||
r.my_end = middle;
|
||||
assert( assert_okay() );
|
||||
assert( r.assert_okay() );
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// End of signatures required by parallel_reduce
|
||||
//------------------------------------------------------------------------
|
||||
NumberType begin() const {return my_begin;}
|
||||
NumberType end() const {return my_end;}
|
||||
SieveRange( NumberType begin, NumberType end, NumberType stride, NumberType grainsize ) :
|
||||
my_begin(begin),
|
||||
my_end(end),
|
||||
my_stride(stride),
|
||||
my_grainsize(grainsize<stride?stride:grainsize)
|
||||
{
|
||||
assert( assert_okay() );
|
||||
}
|
||||
};
|
||||
|
||||
//! Loop body for parallel_reduce.
|
||||
/** parallel_reduce splits the sieve into subsieves.
|
||||
Each subsieve handles a subrange of [0..n]. */
|
||||
class Sieve {
|
||||
public:
|
||||
//! Prime Multiples to consider, and working storage for this subsieve.
|
||||
::Multiples multiples;
|
||||
|
||||
//! NumberType of primes found so far by this subsieve.
|
||||
NumberType count;
|
||||
|
||||
//! Construct Sieve for counting primes in [0..n].
|
||||
Sieve( NumberType n ) :
|
||||
multiples(n),
|
||||
count(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Begin signatures required by parallel_reduce
|
||||
//------------------------------------------------------------------------
|
||||
void operator()( const SieveRange& r ) {
|
||||
NumberType m = multiples.m;
|
||||
if( multiples.is_initialized() ) {
|
||||
// Simply reuse "Multiples" structure from previous window
|
||||
// This works because parallel_reduce always applies
|
||||
// *this from left to right.
|
||||
} else {
|
||||
// Need to initialize "Multiples" because *this is a forked copy
|
||||
// that needs to be set up to start at r.begin().
|
||||
multiples.initialize( r.begin() );
|
||||
}
|
||||
NumberType window_size = m;
|
||||
for( NumberType j=r.begin(); j<r.end(); j+=window_size ) {
|
||||
assert( j%multiples.m==0 );
|
||||
if( j+window_size>r.end() )
|
||||
window_size = r.end()-j;
|
||||
count += multiples.find_primes_in_window( j, window_size );
|
||||
}
|
||||
}
|
||||
void join( Sieve& other ) {
|
||||
count += other.count;
|
||||
// Final value of multiples needs to final value of other multiples,
|
||||
// so that *this can correctly process next window to right.
|
||||
multiples.move( other.multiples );
|
||||
}
|
||||
Sieve( Sieve& other, tbb::split ) :
|
||||
multiples(other.multiples,tbb::split()),
|
||||
count(0)
|
||||
{}
|
||||
//------------------------------------------------------------------------
|
||||
// End of signatures required by parallel_reduce
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//! Count number of primes between 0 and n
|
||||
/** This is the parallel version. */
|
||||
NumberType ParallelCountPrimes( NumberType n , int number_of_threads, NumberType grain_size ) {
|
||||
tbb::global_control c(tbb::global_control::max_allowed_parallelism, number_of_threads);
|
||||
|
||||
// Two is special case
|
||||
NumberType count = n>=2;
|
||||
if( n>=3 ) {
|
||||
Sieve s(n);
|
||||
count += s.multiples.n_factor;
|
||||
if( printPrimes )
|
||||
printf("---\n");
|
||||
using namespace tbb;
|
||||
// Explicit grain size and simple_partitioner() used here instead of automatic grainsize
|
||||
// determination because we want SieveRange to be decomposed down to grainSize or smaller.
|
||||
// Doing so improves odds that the working set fits in cache when evaluating Sieve::operator().
|
||||
parallel_reduce( SieveRange( s.multiples.m, n, s.multiples.m, grain_size ), s, simple_partitioner() );
|
||||
count += s.count;
|
||||
}
|
||||
return count;
|
||||
}
|
40
cs440-acg/ext/tbb/examples/parallel_reduce/primes/primes.h
Normal file
40
cs440-acg/ext/tbb/examples/parallel_reduce/primes/primes.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef PRIMES_H_
|
||||
#define PRIMES_H_
|
||||
|
||||
#if __TBB_MIC_OFFLOAD
|
||||
#pragma offload_attribute (push,target(mic))
|
||||
#endif // __TBB_MIC_OFFLOAD
|
||||
|
||||
#include "../../common/utility/get_default_num_threads.h"
|
||||
#include <cstddef>
|
||||
typedef std::size_t NumberType;
|
||||
|
||||
//! Count number of primes between 0 and n
|
||||
/** This is the serial version. */
|
||||
NumberType SerialCountPrimes( NumberType n);
|
||||
|
||||
//! Count number of primes between 0 and n
|
||||
/** This is the parallel version. */
|
||||
NumberType ParallelCountPrimes( NumberType n, int numberOfThreads= utility::get_default_num_threads(), NumberType grainSize = 1000);
|
||||
|
||||
#if __TBB_MIC_OFFLOAD
|
||||
#pragma offload_attribute (pop)
|
||||
#endif // __TBB_MIC_OFFLOAD
|
||||
|
||||
#endif /* PRIMES_H_ */
|
407
cs440-acg/ext/tbb/examples/parallel_reduce/primes/readme.html
Normal file
407
cs440-acg/ext/tbb/examples/parallel_reduce/primes/readme.html
Normal file
@@ -0,0 +1,407 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
::selection {
|
||||
background: #b7ffb7;
|
||||
}
|
||||
::-moz-selection {
|
||||
background: #b7ffb7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#banner {
|
||||
/* Div for banner */
|
||||
float:left;
|
||||
margin: 0px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
background-color: #0071C5;
|
||||
z-index: 0;
|
||||
}
|
||||
#banner .logo {
|
||||
/* Apply to logo in banner. Add as class to image tag. */
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
margin-top: 15px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 36px;
|
||||
}
|
||||
h1.title {
|
||||
/* Add as class to H1 in banner */
|
||||
font-family: "Intel Clear", Verdana, Arial, sans-serif;
|
||||
font-weight:normal;
|
||||
color: #FFFFFF;
|
||||
font-size: 170%;
|
||||
margin-right: 40px;
|
||||
margin-left: 40px;
|
||||
padding-right: 20px;
|
||||
text-indent: 20px;
|
||||
}
|
||||
.h3-alike {
|
||||
display:inline;
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
color: #0071C5;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
color: #0071C5;
|
||||
}
|
||||
.h4-alike {
|
||||
display:inline;
|
||||
font-size: 1.05em;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
font-family: "Consolas", Monaco, monospace;
|
||||
font-size:small;
|
||||
background: #fafafa;
|
||||
margin: 0;
|
||||
padding-left:20px;
|
||||
}
|
||||
#footer {
|
||||
font-size: small;
|
||||
}
|
||||
code {
|
||||
font-family: "Consolas", Monaco, monospace;
|
||||
}
|
||||
.code-block
|
||||
{
|
||||
padding-left:20px;
|
||||
}
|
||||
.changes {
|
||||
margin: 1em 0;
|
||||
}
|
||||
.changes input:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.changes input:hover:after {
|
||||
padding-left: 16px;
|
||||
font-size: 10px;
|
||||
content: 'More';
|
||||
}
|
||||
.changes input:checked:hover:after {
|
||||
content: 'Less';
|
||||
}
|
||||
.changes input + .show-hide {
|
||||
display: none;
|
||||
}
|
||||
.changes input:checked + .show-hide {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
}
|
||||
ul li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
ul li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.disc {
|
||||
list-style-type:disc
|
||||
}
|
||||
.circ {
|
||||
list-style-type:circle
|
||||
}
|
||||
|
||||
.single {
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* Table styles */
|
||||
table{
|
||||
margin-bottom:5pt;
|
||||
border-collapse:collapse;
|
||||
margin-left:0px;
|
||||
margin-top:0.3em;
|
||||
font-size:10pt;
|
||||
}
|
||||
tr{
|
||||
vertical-align:top;
|
||||
}
|
||||
th,
|
||||
th h3{
|
||||
padding:4px;
|
||||
text-align:left;
|
||||
background-color:#0071C5;
|
||||
font-weight:bold;
|
||||
margin-top:1px;
|
||||
margin-bottom:0;
|
||||
color:#FFFFFF;
|
||||
font-size:10pt;
|
||||
vertical-align:middle;
|
||||
}
|
||||
th{
|
||||
border:1px #dddddd solid;
|
||||
padding-top:2px;
|
||||
padding-bottom:0px;
|
||||
padding-right:3px;
|
||||
padding-left:3px;
|
||||
}
|
||||
td{
|
||||
border:1px #dddddd solid;
|
||||
vertical-align:top;
|
||||
font-size:100%;
|
||||
text-align:left;
|
||||
margin-bottom:0;
|
||||
}
|
||||
td,
|
||||
td p{
|
||||
margin-top:0;
|
||||
margin-left:0;
|
||||
text-align:left;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
}
|
||||
td p{
|
||||
margin-bottom:0;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
padding-right:5px;
|
||||
padding-left:1px;
|
||||
}
|
||||
.noborder{
|
||||
border:0px none;
|
||||
}
|
||||
.noborder1stcol{
|
||||
border:0px none;
|
||||
padding-left:0pt;
|
||||
}
|
||||
td ol{
|
||||
font-size:inherit;
|
||||
margin-left:28px;
|
||||
}
|
||||
td ul{
|
||||
font-size:inherit;
|
||||
margin-left:24px;
|
||||
}
|
||||
.DefListTbl{
|
||||
width:90%;
|
||||
margin-left:-3pt;
|
||||
}
|
||||
.syntaxdiagramtbl{
|
||||
margin-left:-3pt;
|
||||
}
|
||||
.sdtbl{
|
||||
}
|
||||
.sdrow{
|
||||
}
|
||||
.sdtblp{
|
||||
border:0px none;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
margin-bottom:0;
|
||||
padding-bottom:0px;
|
||||
padding-top:5px;
|
||||
padding-left:0px;
|
||||
padding-right:5px;
|
||||
vertical-align:top;
|
||||
}
|
||||
.idepara, .ide_para{
|
||||
border:0px none;
|
||||
font-size:inherit;
|
||||
line-height:120%;
|
||||
margin-bottom:0;
|
||||
padding-bottom:0px;
|
||||
padding-top:5px;
|
||||
padding-left:0px;
|
||||
padding-right:5px;
|
||||
vertical-align:top;
|
||||
}
|
||||
|
||||
.specs {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
.specs td, .specs th {
|
||||
font-size: 14px;
|
||||
}
|
||||
.specs td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
.specs td td, .specs td th {
|
||||
border: none;
|
||||
}
|
||||
.specs td, .specs td td, .specs td th {
|
||||
padding: 0 0.2em 0.2em;
|
||||
text-align: center;
|
||||
}
|
||||
.specs td tr:last-child td,
|
||||
.specs td tr:last-child th {
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
.serial-time {
|
||||
}
|
||||
.modified-time {
|
||||
width: 6.5em;
|
||||
}
|
||||
.compiler {
|
||||
}
|
||||
.comp-opt {
|
||||
}
|
||||
.sys-specs {
|
||||
width: 18em;
|
||||
}
|
||||
.note {
|
||||
font-size:small;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
<title>Intel® Threading Building Blocks. Primes sample</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="banner">
|
||||
<img class="logo" src="data:image/png;base64,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
|
||||
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
|
||||
<h1 class="title">Intel® Threading Building Blocks.<br>Primes sample</h1>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Parallel version of the Sieve of Eratosthenes.
|
||||
<br><br>
|
||||
The example can be built in the offload version to run on Intel® Many Integrated Core (Intel® MIC) Architecture based coprocessor (see <a href="../../index.html">build instructions</a>).
|
||||
</p>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">System Requirements</div>
|
||||
<input type="checkbox">
|
||||
<div class="show-hide">
|
||||
<p>
|
||||
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Files</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><a href="main.cpp">main.cpp</a>
|
||||
<dd>Main program which parses command line options and runs the algorithm with different numbers of threads.
|
||||
<dt><a href="primes.h">primes.h</a>
|
||||
<dd>The Sieve of Eratosthenes interface.
|
||||
<dt><a href="primes.cpp">primes.cpp</a>
|
||||
<dd>The Sieve of Eratosthenes implementation.
|
||||
<dt><a href="Makefile">Makefile</a>
|
||||
<dd>Makefile for building the example.
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Directories</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><a href="msvs/">msvs</a>
|
||||
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
|
||||
<dt><a href="xcode/">xcode</a>
|
||||
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
|
||||
</dl>
|
||||
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Build instructions</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Usage</div>
|
||||
<input type="checkbox" checked="checked">
|
||||
<div class="show-hide">
|
||||
<dl>
|
||||
<dt><tt>primes <i>-h</i></tt>
|
||||
<dd>Prints the help for command line options
|
||||
<dt><tt>primes [<i>n-of-threads</i>=value] [<i>number</i>=value] [<i>grain-size</i>=value] [<i>n-of-repeats</i>=value] [<i>silent</i>]</tt>
|
||||
<dt><tt>primes [<i>n-of-threads</i> [<i>number</i> [<i>grain-size</i> [<i>n-of-repeats</i>]]]][<i>silent</i>]</tt>
|
||||
<dd><i>n-of-threads</i> is the number of threads to use; a range of the form <i>low</i>[:<i>high</i>], where low and optional high are non-negative integers or 'auto' for a platform-specific default number.<br>
|
||||
<i>number</i> is an upper bound of range to search primes in, must be a positive integer.<br>
|
||||
<i>grain-size</i> is an optional grain size, must be a positive integer. <br>
|
||||
<i>n-of-repeats</i> is a number of the calculation repeats, must be a positive integer.<br>
|
||||
<i>silent</i> - no output except elapsed time.<br>
|
||||
<dt>To run a short version of this example, e.g., for use with Intel® Parallel Inspector:
|
||||
<dd>Build a <i>debug</i> version of the example
|
||||
(see the <a href="../../index.html">build instructions</a>).
|
||||
<br>Run it with a small problem size and the desired number of threads, e.g., <tt>primes 4 100000</tt>.
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<a href="../index.html">Up to parent directory</a>
|
||||
<hr>
|
||||
<div class="changes">
|
||||
<div class="h3-alike">Legal Information</div>
|
||||
<input type="checkbox">
|
||||
<div class="show-hide">
|
||||
<p>
|
||||
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
|
||||
<br>* Other names and brands may be claimed as the property of others.
|
||||
<br>© 2020, Intel Corporation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -0,0 +1,268 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A1F593A60B8F042A00073279 /* primes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* primes.cpp */; };
|
||||
EA8D882D1301731B00385DE1 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA8D882C1301731B00385DE1 /* main.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildRule section */
|
||||
C3C5895B218B692000DAC94C /* PBXBuildRule */ = {
|
||||
isa = PBXBuildRule;
|
||||
compilerSpec = com.intel.compilers.icc.latest;
|
||||
fileType = sourcecode.cpp;
|
||||
isEditable = 1;
|
||||
outputFiles = (
|
||||
);
|
||||
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
|
||||
};
|
||||
/* End PBXBuildRule section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 12;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
8DD76F6C0486A84900D96B5E /* primes */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = primes; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1F593A50B8F042A00073279 /* primes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = primes.cpp; path = ../primes.cpp; sourceTree = SOURCE_ROOT; };
|
||||
EA8D882B130172E400385DE1 /* primes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = primes.h; path = ../primes.h; sourceTree = SOURCE_ROOT; };
|
||||
EA8D882C1301731B00385DE1 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../main.cpp; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8DD76F660486A84900D96B5E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
08FB7794FE84155DC02AAC07 /* primes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
);
|
||||
name = primes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7795FE84155DC02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EA8D882C1301731B00385DE1 /* main.cpp */,
|
||||
EA8D882B130172E400385DE1 /* primes.h */,
|
||||
A1F593A50B8F042A00073279 /* primes.cpp */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8DD76F6C0486A84900D96B5E /* primes */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8DD76F620486A84900D96B5E /* primes */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "primes" */;
|
||||
buildPhases = (
|
||||
8DD76F640486A84900D96B5E /* Sources */,
|
||||
8DD76F660486A84900D96B5E /* Frameworks */,
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
C3C5895B218B692000DAC94C /* PBXBuildRule */,
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = primes;
|
||||
productInstallPath = "$(HOME)/bin";
|
||||
productName = primes;
|
||||
productReference = 8DD76F6C0486A84900D96B5E /* primes */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1000;
|
||||
};
|
||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "primes" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* primes */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8DD76F620486A84900D96B5E /* primes */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8DD76F640486A84900D96B5E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1F593A60B8F042A00073279 /* primes.cpp in Sources */,
|
||||
EA8D882D1301731B00385DE1 /* main.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
PRODUCT_NAME = primes;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Debug64;
|
||||
};
|
||||
A1F593C70B8F0E6E00073279 /* Release64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_VERSION = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
PRODUCT_NAME = primes;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release64;
|
||||
};
|
||||
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_ENABLE_CPP_RTTI = YES;
|
||||
GCC_MODEL_TUNING = "";
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/include",
|
||||
/opt/intel/tbb/include,
|
||||
);
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/lib",
|
||||
/opt/intel/tbb/lib,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-m64",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-m64",
|
||||
"-ltbb_debug",
|
||||
);
|
||||
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
|
||||
SYMROOT = "/tmp/tbb-$(USER)";
|
||||
VALID_ARCHS = x86_64;
|
||||
};
|
||||
name = Debug64;
|
||||
};
|
||||
A1F593C90B8F0E6E00073279 /* Release64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = YES;
|
||||
GCC_MODEL_TUNING = "";
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/include",
|
||||
/opt/intel/tbb/include,
|
||||
);
|
||||
ICC_CXX_LANG_DIALECT = "c++11";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(TBBROOT)/lib",
|
||||
/opt/intel/tbb/lib,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-m64",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-m64",
|
||||
"-ltbb",
|
||||
);
|
||||
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
|
||||
SYMROOT = "/tmp/tbb-$(USER)";
|
||||
VALID_ARCHS = x86_64;
|
||||
};
|
||||
name = Release64;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "primes" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1F593C60B8F0E6E00073279 /* Debug64 */,
|
||||
A1F593C70B8F0E6E00073279 /* Release64 */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release64;
|
||||
};
|
||||
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "primes" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1F593C80B8F0E6E00073279 /* Debug64 */,
|
||||
A1F593C90B8F0E6E00073279 /* Release64 */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release64;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
}
|
Reference in New Issue
Block a user