Disabled external gits
This commit is contained in:
31
cs440-acg/ext/tbb/examples/test_all/fibonacci/CMakeLists.txt
Normal file
31
cs440-acg/ext/tbb/examples/test_all/fibonacci/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2019-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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
|
||||
|
||||
project(fibonacci CXX)
|
||||
|
||||
if (NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
|
||||
add_executable(fibonacci Fibonacci.cpp)
|
||||
|
||||
# find_package will search for available TBBConfig using variables CMAKE_PREFIX_PATH and TBB_DIR.
|
||||
find_package(TBB REQUIRED tbb)
|
||||
|
||||
target_link_libraries(fibonacci
|
||||
${TBB_IMPORTED_TARGETS} # Link TBB imported targets to the executable; "TBB::tbb" can be used instead of "${TBB_IMPORTED_TARGETS}".
|
||||
$<$<PLATFORM_ID:Linux>:rt>) # Link "rt" library on Linux
|
624
cs440-acg/ext/tbb/examples/test_all/fibonacci/Fibonacci.cpp
Normal file
624
cs440-acg/ext/tbb/examples/test_all/fibonacci/Fibonacci.cpp
Normal file
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
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 Fibonacci numbers in different ways.
|
||||
Arguments are: [ Number [Threads [Repeats]]]
|
||||
The defaults are Number=500 Threads=1:4 Repeats=1.
|
||||
|
||||
The point of this program is to check that the library is working properly.
|
||||
Most of the computations are deliberately silly and not expected to
|
||||
show any speedup on multiprocessors.
|
||||
*/
|
||||
|
||||
// enable assertions
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include "tbb/task.h"
|
||||
#include "tbb/tick_count.h"
|
||||
#include "tbb/blocked_range.h"
|
||||
#include "tbb/concurrent_vector.h"
|
||||
#include "tbb/concurrent_queue.h"
|
||||
#include "tbb/concurrent_hash_map.h"
|
||||
#include "tbb/parallel_while.h"
|
||||
#include "tbb/parallel_for.h"
|
||||
#include "tbb/parallel_reduce.h"
|
||||
#include "tbb/parallel_scan.h"
|
||||
#include "tbb/pipeline.h"
|
||||
#include "tbb/spin_mutex.h"
|
||||
#include "tbb/queuing_mutex.h"
|
||||
#include "tbb/global_control.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace tbb;
|
||||
|
||||
//! type used for Fibonacci number computations
|
||||
typedef long long value;
|
||||
|
||||
//! Matrix 2x2 class
|
||||
struct Matrix2x2
|
||||
{
|
||||
//! Array of values
|
||||
value v[2][2];
|
||||
Matrix2x2() {}
|
||||
Matrix2x2(value v00, value v01, value v10, value v11) {
|
||||
v[0][0] = v00; v[0][1] = v01; v[1][0] = v10; v[1][1] = v11;
|
||||
}
|
||||
Matrix2x2 operator * (const Matrix2x2 &to) const; //< Multiply two Matrices
|
||||
};
|
||||
//! Identity matrix
|
||||
static const Matrix2x2 MatrixIdentity(1, 0, 0, 1);
|
||||
//! Default matrix to multiply
|
||||
static const Matrix2x2 Matrix1110(1, 1, 1, 0);
|
||||
//! Raw arrays matrices multiply
|
||||
void Matrix2x2Multiply(const value a[2][2], const value b[2][2], value c[2][2]);
|
||||
|
||||
/////////////////////// Serial methods ////////////////////////
|
||||
|
||||
//! Plain serial sum
|
||||
value SerialFib(int n)
|
||||
{
|
||||
if(n < 2)
|
||||
return n;
|
||||
value a = 0, b = 1, sum; int i;
|
||||
for( i = 2; i <= n; i++ )
|
||||
{ // n is really index of Fibonacci number
|
||||
sum = a + b; a = b; b = sum;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
//! Serial n-1 matrices multiplication
|
||||
value SerialMatrixFib(int n)
|
||||
{
|
||||
value c[2][2], a[2][2] = {{1, 1}, {1, 0}}, b[2][2] = {{1, 1}, {1, 0}}; int i;
|
||||
for(i = 2; i < n; i++)
|
||||
{ // Using condition to prevent copying of values
|
||||
if(i & 1) Matrix2x2Multiply(a, c, b);
|
||||
else Matrix2x2Multiply(a, b, c);
|
||||
}
|
||||
return (i & 1) ? c[0][0] : b[0][0]; // get result from upper left cell
|
||||
}
|
||||
//! Recursive summing. Just for complete list of serial algorithms, not used
|
||||
value SerialRecursiveFib(int n)
|
||||
{
|
||||
value result;
|
||||
if(n < 2)
|
||||
result = n;
|
||||
else
|
||||
result = SerialRecursiveFib(n - 1) + SerialRecursiveFib(n - 2);
|
||||
return result;
|
||||
}
|
||||
//! Introducing of queue method in serial
|
||||
value SerialQueueFib(int n)
|
||||
{
|
||||
concurrent_queue<Matrix2x2> Q;
|
||||
for(int i = 1; i < n; i++)
|
||||
Q.push(Matrix1110);
|
||||
Matrix2x2 A, B;
|
||||
while(true) {
|
||||
while( !Q.try_pop(A) ) std::this_thread::yield();
|
||||
if(Q.empty()) break;
|
||||
while( !Q.try_pop(B) ) std::this_thread::yield();
|
||||
Q.push(A * B);
|
||||
}
|
||||
return A.v[0][0];
|
||||
}
|
||||
//! Trying to use concurrent_vector
|
||||
value SerialVectorFib(int n)
|
||||
{
|
||||
concurrent_vector<value> A;
|
||||
A.grow_by(2);
|
||||
A[0] = 0; A[1] = 1;
|
||||
for( int i = 2; i <= n; i++)
|
||||
{
|
||||
A.grow_to_at_least(i+1);
|
||||
A[i] = A[i-1] + A[i-2];
|
||||
}
|
||||
return A[n];
|
||||
}
|
||||
|
||||
///////////////////// Parallel methods ////////////////////////
|
||||
|
||||
// *** Serial shared by mutexes *** //
|
||||
|
||||
//! Shared glabals
|
||||
value SharedA = 0, SharedB = 1; int SharedI = 1, SharedN;
|
||||
|
||||
//! Template task class which computes Fibonacci numbers with shared globals
|
||||
template<typename M>
|
||||
class SharedSerialFibBody {
|
||||
M &mutex;
|
||||
public:
|
||||
SharedSerialFibBody( M &m ) : mutex( m ) {}
|
||||
//! main loop
|
||||
void operator()( const blocked_range<int>& range ) const {
|
||||
for(;;) {
|
||||
typename M::scoped_lock lock( mutex );
|
||||
if(SharedI >= SharedN) break;
|
||||
value sum = SharedA + SharedB;
|
||||
SharedA = SharedB; SharedB = sum;
|
||||
++SharedI;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if __TBB_CPP11_PRESENT
|
||||
template<>
|
||||
void SharedSerialFibBody<std::mutex>::operator()( const blocked_range<int>& range ) const {
|
||||
for(;;) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
if(SharedI >= SharedN) break;
|
||||
value sum = SharedA + SharedB;
|
||||
SharedA = SharedB; SharedB = sum;
|
||||
++SharedI;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Root function
|
||||
template<class M>
|
||||
value SharedSerialFib(int n)
|
||||
{
|
||||
SharedA = 0; SharedB = 1; SharedI = 1; SharedN = n; M mutex;
|
||||
parallel_for( blocked_range<int>(0,4,1), SharedSerialFibBody<M>( mutex ) );
|
||||
return SharedB;
|
||||
}
|
||||
|
||||
// *** Serial shared by concurrent hash map *** //
|
||||
|
||||
//! Hash comparer
|
||||
struct IntHashCompare {
|
||||
bool equal( const int j, const int k ) const { return j == k; }
|
||||
unsigned long hash( const int k ) const { return (unsigned long)k; }
|
||||
};
|
||||
//! NumbersTable type based on concurrent_hash_map
|
||||
typedef concurrent_hash_map<int, value, IntHashCompare> NumbersTable;
|
||||
//! task for serial method using shared concurrent_hash_map
|
||||
class ConcurrentHashSerialFibTask: public task {
|
||||
NumbersTable &Fib;
|
||||
int my_n;
|
||||
public:
|
||||
//! constructor
|
||||
ConcurrentHashSerialFibTask( NumbersTable &cht, int n ) : Fib(cht), my_n(n) { }
|
||||
//! executing task
|
||||
task* execute() /*override*/ {
|
||||
for( int i = 2; i <= my_n; ++i ) { // there is no difference in to recycle or to make loop
|
||||
NumbersTable::const_accessor f1, f2; // same as iterators
|
||||
if( !Fib.find(f1, i-1) || !Fib.find(f2, i-2) ) {
|
||||
// Something is seriously wrong, because i-1 and i-2 must have been inserted
|
||||
// earlier by this thread or another thread.
|
||||
assert(0);
|
||||
}
|
||||
value sum = f1->second + f2->second;
|
||||
NumbersTable::const_accessor fsum;
|
||||
Fib.insert(fsum, make_pair(i, sum)); // inserting
|
||||
assert( fsum->second == sum ); // check value
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//! Root function
|
||||
value ConcurrentHashSerialFib(int n)
|
||||
{
|
||||
NumbersTable Fib;
|
||||
bool okay;
|
||||
okay = Fib.insert( make_pair(0, 0) ); assert(okay); // assign initial values
|
||||
okay = Fib.insert( make_pair(1, 1) ); assert(okay);
|
||||
|
||||
task_list list;
|
||||
// allocate tasks
|
||||
list.push_back(*new(task::allocate_root()) ConcurrentHashSerialFibTask(Fib, n));
|
||||
list.push_back(*new(task::allocate_root()) ConcurrentHashSerialFibTask(Fib, n));
|
||||
task::spawn_root_and_wait(list);
|
||||
NumbersTable::const_accessor fresult;
|
||||
okay = Fib.find( fresult, n );
|
||||
assert(okay);
|
||||
return fresult->second;
|
||||
}
|
||||
|
||||
// *** Queue with parallel_for and parallel_while *** //
|
||||
|
||||
//! Stream of matrices
|
||||
struct QueueStream {
|
||||
volatile bool producer_is_done;
|
||||
concurrent_queue<Matrix2x2> Queue;
|
||||
//! Get pair of matricies if present
|
||||
bool pop_if_present( pair<Matrix2x2, Matrix2x2> &mm ) {
|
||||
// get first matrix if present
|
||||
if(!Queue.try_pop(mm.first)) return false;
|
||||
// get second matrix if present
|
||||
if(!Queue.try_pop(mm.second)) {
|
||||
// if not, then push back first matrix
|
||||
Queue.push(mm.first); return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//! Functor for parallel_for which fills the queue
|
||||
struct parallel_forFibBody {
|
||||
QueueStream &my_stream;
|
||||
//! fill functor arguments
|
||||
parallel_forFibBody(QueueStream &s) : my_stream(s) { }
|
||||
//! iterate thorough range
|
||||
void operator()( const blocked_range<int> &range ) const {
|
||||
int i_end = range.end();
|
||||
for( int i = range.begin(); i != i_end; ++i ) {
|
||||
my_stream.Queue.push( Matrix1110 ); // push initial matrix
|
||||
}
|
||||
}
|
||||
};
|
||||
//! Functor for parallel_while which process the queue
|
||||
class parallel_whileFibBody
|
||||
{
|
||||
QueueStream &my_stream;
|
||||
parallel_while<parallel_whileFibBody> &my_while;
|
||||
public:
|
||||
typedef pair<Matrix2x2, Matrix2x2> argument_type;
|
||||
//! fill functor arguments
|
||||
parallel_whileFibBody(parallel_while<parallel_whileFibBody> &w, QueueStream &s)
|
||||
: my_while(w), my_stream(s) { }
|
||||
//! process pair of matrices
|
||||
void operator() (argument_type mm) const {
|
||||
mm.first = mm.first * mm.second;
|
||||
// note: it can run concurrently with QueueStream::pop_if_present()
|
||||
if(my_stream.Queue.try_pop(mm.second))
|
||||
my_while.add( mm ); // now, two matrices available. Add next iteration.
|
||||
else my_stream.Queue.push( mm.first ); // or push back calculated value if queue is empty
|
||||
}
|
||||
};
|
||||
|
||||
//! Parallel queue's filling task
|
||||
struct QueueInsertTask: public task {
|
||||
QueueStream &my_stream;
|
||||
int my_n;
|
||||
//! fill task arguments
|
||||
QueueInsertTask( int n, QueueStream &s ) : my_n(n), my_stream(s) { }
|
||||
//! executing task
|
||||
task* execute() /*override*/ {
|
||||
// Execute of parallel pushing of n-1 initial matrices
|
||||
parallel_for( blocked_range<int>( 1, my_n, 10 ), parallel_forFibBody(my_stream) );
|
||||
my_stream.producer_is_done = true;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
//! Parallel queue's processing task
|
||||
struct QueueProcessTask: public task {
|
||||
QueueStream &my_stream;
|
||||
//! fill task argument
|
||||
QueueProcessTask( QueueStream &s ) : my_stream(s) { }
|
||||
//! executing task
|
||||
task* execute() /*override*/ {
|
||||
while( !my_stream.producer_is_done || my_stream.Queue.unsafe_size()>1 ) {
|
||||
parallel_while<parallel_whileFibBody> w; // run while loop in parallel
|
||||
w.run( my_stream, parallel_whileFibBody( w, my_stream ) );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
//! Root function
|
||||
value ParallelQueueFib(int n)
|
||||
{
|
||||
QueueStream stream;
|
||||
stream.producer_is_done = false;
|
||||
task_list list;
|
||||
list.push_back(*new(task::allocate_root()) QueueInsertTask( n, stream ));
|
||||
list.push_back(*new(task::allocate_root()) QueueProcessTask( stream ));
|
||||
// If there is only a single thread, the first task in the list runs to completion
|
||||
// before the second task in the list starts.
|
||||
task::spawn_root_and_wait(list);
|
||||
assert(stream.Queue.unsafe_size() == 1); // it is easy to lose some work
|
||||
Matrix2x2 M;
|
||||
bool result = stream.Queue.try_pop( M ); // get last matrix
|
||||
assert( result );
|
||||
return M.v[0][0]; // and result number
|
||||
}
|
||||
|
||||
// *** Queue with parallel_pipeline *** //
|
||||
|
||||
typedef concurrent_queue<Matrix2x2> queue_t;
|
||||
namespace parallel_pipeline_ns {
|
||||
std::atomic<int> N; //< index of Fibonacci number minus 1
|
||||
queue_t Queue;
|
||||
}
|
||||
|
||||
//! functor to fills queue
|
||||
struct InputFunc {
|
||||
InputFunc( ) { }
|
||||
queue_t* operator()(tbb::flow_control& fc) const {
|
||||
using namespace parallel_pipeline_ns;
|
||||
|
||||
int n = --N;
|
||||
if(n <= 0) {
|
||||
fc.stop();
|
||||
return NULL;
|
||||
}
|
||||
Queue.push( Matrix1110 );
|
||||
return &Queue;
|
||||
}
|
||||
};
|
||||
//! functor to process queue
|
||||
struct MultiplyFunc {
|
||||
MultiplyFunc( ) { }
|
||||
void operator()(queue_t* queue) const {
|
||||
//concurrent_queue<Matrix2x2> &Queue = *static_cast<concurrent_queue<Matrix2x2> *>(p);
|
||||
Matrix2x2 m1, m2;
|
||||
// get two elements
|
||||
while( !queue->try_pop( m1 ) ) std::this_thread::yield();
|
||||
while( !queue->try_pop( m2 ) ) std::this_thread::yield();
|
||||
m1 = m1 * m2; // process them
|
||||
queue->push( m1 ); // and push back
|
||||
}
|
||||
};
|
||||
//! Root function
|
||||
value ParallelPipeFib(int n)
|
||||
{
|
||||
using namespace parallel_pipeline_ns;
|
||||
|
||||
N = n-1;
|
||||
Queue.push( Matrix1110 );
|
||||
|
||||
tbb::parallel_pipeline(
|
||||
n,
|
||||
tbb::make_filter<void,queue_t*>(
|
||||
tbb::filter::parallel, InputFunc() )
|
||||
&
|
||||
tbb::make_filter<queue_t*,void>(
|
||||
tbb::filter::parallel, MultiplyFunc() )
|
||||
);
|
||||
|
||||
assert( Queue.unsafe_size()==1 );
|
||||
Matrix2x2 M;
|
||||
bool result = Queue.try_pop( M ); // get last element
|
||||
assert( result );
|
||||
value res = M.v[0][0]; // get value
|
||||
Queue.clear();
|
||||
return res;
|
||||
}
|
||||
|
||||
// *** parallel_reduce *** //
|
||||
|
||||
//! Functor for parallel_reduce
|
||||
struct parallel_reduceFibBody {
|
||||
Matrix2x2 sum;
|
||||
int split_flag; //< flag to make one less operation for split bodies
|
||||
//! Constructor fills sum with initial matrix
|
||||
parallel_reduceFibBody() : sum( Matrix1110 ), split_flag(0) { }
|
||||
//! Splitting constructor
|
||||
parallel_reduceFibBody( parallel_reduceFibBody& other, split ) : sum( Matrix1110 ), split_flag(1/*note that it is split*/) {}
|
||||
//! Join point
|
||||
void join( parallel_reduceFibBody &s ) {
|
||||
sum = sum * s.sum;
|
||||
}
|
||||
//! Process multiplications
|
||||
void operator()( const blocked_range<int> &r ) {
|
||||
for( int k = r.begin() + split_flag; k < r.end(); ++k )
|
||||
sum = sum * Matrix1110;
|
||||
split_flag = 0; // reset flag, because this method can be reused for next range
|
||||
}
|
||||
};
|
||||
//! Root function
|
||||
value parallel_reduceFib(int n)
|
||||
{
|
||||
parallel_reduceFibBody b;
|
||||
parallel_reduce(blocked_range<int>(2, n, 3), b); // do parallel reduce on range [2, n) for b
|
||||
return b.sum.v[0][0];
|
||||
}
|
||||
|
||||
// *** parallel_scan *** //
|
||||
|
||||
//! Functor for parallel_scan
|
||||
struct parallel_scanFibBody {
|
||||
/** Though parallel_scan is usually used to accumulate running sums,
|
||||
it can be used to accumulate running products too. */
|
||||
Matrix2x2 product;
|
||||
/** Pointer to output sequence */
|
||||
value* const output;
|
||||
//! Constructor sets product to identity matrix
|
||||
parallel_scanFibBody(value* output_) : product( MatrixIdentity ), output(output_) {}
|
||||
//! Splitting constructor
|
||||
parallel_scanFibBody( parallel_scanFibBody &b, split) : product( MatrixIdentity ), output(b.output) {}
|
||||
//! Method for merging summary information from a, which was split off from *this, into *this.
|
||||
void reverse_join( parallel_scanFibBody &a ) {
|
||||
// When using non-commutative reduction operation, reverse_join
|
||||
// should put argument "a" on the left side of the operation.
|
||||
// The reversal from the argument order is why the method is
|
||||
// called "reverse_join" instead of "join".
|
||||
product = a.product * product;
|
||||
}
|
||||
//! Method for assigning final result back to original body.
|
||||
void assign( parallel_scanFibBody &b ) {
|
||||
product = b.product;
|
||||
}
|
||||
//! Compute matrix running product.
|
||||
/** Tag indicates whether is is the final scan over the range, or
|
||||
just a helper "prescan" that is computing a partial reduction. */
|
||||
template<typename Tag>
|
||||
void operator()( const blocked_range<int> &r, Tag tag) {
|
||||
for( int k = r.begin(); k < r.end(); ++k ) {
|
||||
// Code performs an "exclusive" scan, which outputs a value *before* updating the product.
|
||||
// For an "inclusive" scan, output the value after the update.
|
||||
if( tag.is_final_scan() )
|
||||
output[k] = product.v[0][1];
|
||||
product = product * Matrix1110;
|
||||
}
|
||||
}
|
||||
};
|
||||
//! Root function
|
||||
value parallel_scanFib(int n)
|
||||
{
|
||||
value* output = new value[n];
|
||||
parallel_scanFibBody b(output);
|
||||
parallel_scan(blocked_range<int>(0, n, 3), b);
|
||||
// output[0..n-1] now contains the Fibonacci sequence (modulo integer wrap-around).
|
||||
// Check the last two values for correctness.
|
||||
assert( n<2 || output[n-2]+output[n-1]==b.product.v[0][1] );
|
||||
delete[] output;
|
||||
return b.product.v[0][1];
|
||||
}
|
||||
|
||||
// *** Raw tasks *** //
|
||||
|
||||
//! task class which computes Fibonacci numbers by Lucas formula
|
||||
struct FibTask: public task {
|
||||
const int n;
|
||||
value& sum;
|
||||
value x, y;
|
||||
bool second_phase; //< flag of continuation
|
||||
// task arguments
|
||||
FibTask( int n_, value& sum_ ) :
|
||||
n(n_), sum(sum_), second_phase(false)
|
||||
{}
|
||||
//! Execute task
|
||||
task* execute() /*override*/ {
|
||||
// Using Lucas' formula here
|
||||
if( second_phase ) { // children finished
|
||||
sum = n&1 ? x*x + y*y : x*x - y*y;
|
||||
return NULL;
|
||||
}
|
||||
if( n <= 2 ) {
|
||||
sum = n!=0;
|
||||
return NULL;
|
||||
} else {
|
||||
recycle_as_continuation(); // repeat this task when children finish
|
||||
second_phase = true; // mark second phase
|
||||
FibTask& a = *new( allocate_child() ) FibTask( n/2 + 1, x );
|
||||
FibTask& b = *new( allocate_child() ) FibTask( n/2 - 1 + (n&1), y );
|
||||
set_ref_count(2);
|
||||
spawn( a );
|
||||
return &b;
|
||||
}
|
||||
}
|
||||
};
|
||||
//! Root function
|
||||
value ParallelTaskFib(int n) {
|
||||
value sum;
|
||||
FibTask& a = *new(task::allocate_root()) FibTask(n, sum);
|
||||
task::spawn_root_and_wait(a);
|
||||
return sum;
|
||||
}
|
||||
|
||||
/////////////////////////// Main ////////////////////////////////////////////////////
|
||||
|
||||
//! A closed range of int.
|
||||
struct IntRange {
|
||||
int low;
|
||||
int high;
|
||||
void set_from_string( const char* s );
|
||||
IntRange( int low_, int high_ ) : low(low_), high(high_) {}
|
||||
};
|
||||
|
||||
void IntRange::set_from_string( const char* s ) {
|
||||
char* end;
|
||||
high = low = strtol(s,&end,0);
|
||||
switch( *end ) {
|
||||
case ':':
|
||||
high = strtol(end+1,0,0);
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
printf("unexpected character = %c\n",*end);
|
||||
}
|
||||
}
|
||||
|
||||
//! Tick count for start
|
||||
static tick_count t0;
|
||||
|
||||
//! Verbose output flag
|
||||
static bool Verbose = false;
|
||||
|
||||
typedef value (*MeasureFunc)(int);
|
||||
//! Measure ticks count in loop [2..n]
|
||||
value Measure(const char *name, MeasureFunc func, int n)
|
||||
{
|
||||
value result;
|
||||
if(Verbose) printf("%s",name);
|
||||
t0 = tick_count::now();
|
||||
for(int number = 2; number <= n; number++)
|
||||
result = func(number);
|
||||
if(Verbose) printf("\t- in %f msec\n", (tick_count::now() - t0).seconds()*1000);
|
||||
return result;
|
||||
}
|
||||
|
||||
//! program entry
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if(argc>1) Verbose = true;
|
||||
int NumbersCount = argc>1 ? strtol(argv[1],0,0) : 500;
|
||||
IntRange NThread(1,4);// Number of threads to use.
|
||||
if(argc>2) NThread.set_from_string(argv[2]);
|
||||
unsigned long ntrial = argc>3? (unsigned long)strtoul(argv[3],0,0) : 1;
|
||||
value result, sum;
|
||||
|
||||
if(Verbose) printf("Fibonacci numbers example. Generating %d numbers..\n", NumbersCount);
|
||||
|
||||
result = Measure("Serial loop", SerialFib, NumbersCount);
|
||||
sum = Measure("Serial matrix", SerialMatrixFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Serial vector", SerialVectorFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Serial queue", SerialQueueFib, NumbersCount); assert(result == sum);
|
||||
// now in parallel
|
||||
for( unsigned long i=0; i<ntrial; ++i ) {
|
||||
for(int threads = NThread.low; threads <= NThread.high; threads *= 2)
|
||||
{
|
||||
tbb::global_control c(tbb::global_control::max_allowed_parallelism, threads);
|
||||
if(Verbose) printf("\nThreads number is %d\n", threads);
|
||||
|
||||
sum = Measure("Shared serial (mutex)\t", SharedSerialFib<mutex>, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Shared serial (spin_mutex)", SharedSerialFib<spin_mutex>, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Shared serial (queuing_mutex)", SharedSerialFib<queuing_mutex>, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Shared serial (Conc.HashTable)", ConcurrentHashSerialFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Parallel while+for/queue", ParallelQueueFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Parallel pipe/queue\t", ParallelPipeFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Parallel reduce\t\t", parallel_reduceFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Parallel scan\t\t", parallel_scanFib, NumbersCount); assert(result == sum);
|
||||
sum = Measure("Parallel tasks\t\t", ParallelTaskFib, NumbersCount); assert(result == sum);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
if(Verbose) printf("Fibonacci number #%d modulo 2^64 is %lld\n\n", NumbersCount, result);
|
||||
#else
|
||||
if(Verbose) printf("Fibonacci number #%d modulo 2^64 is %I64d\n\n", NumbersCount, result);
|
||||
#endif
|
||||
}
|
||||
if(!Verbose) printf("TEST PASSED\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Utils
|
||||
|
||||
void Matrix2x2Multiply(const value a[2][2], const value b[2][2], value c[2][2])
|
||||
{
|
||||
for( int i = 0; i <= 1; i++)
|
||||
for( int j = 0; j <= 1; j++)
|
||||
c[i][j] = a[i][0]*b[0][j] + a[i][1]*b[1][j];
|
||||
}
|
||||
|
||||
Matrix2x2 Matrix2x2::operator *(const Matrix2x2 &to) const
|
||||
{
|
||||
Matrix2x2 result;
|
||||
Matrix2x2Multiply(v, to.v, result.v);
|
||||
return result;
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
# 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=Fibonacci
|
||||
ARGS=
|
||||
|
||||
# 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 /D _WIN32_WINNT=0x0501 $(CXXFLAGS)
|
||||
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
|
||||
|
||||
all: release test
|
||||
release: compiler_check
|
||||
$(CXX) *.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
|
||||
debug: compiler_check
|
||||
$(CXX) *.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)
|
||||
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
|
402
cs440-acg/ext/tbb/examples/test_all/fibonacci/readme.html
Normal file
402
cs440-acg/ext/tbb/examples/test_all/fibonacci/readme.html
Normal file
@@ -0,0 +1,402 @@
|
||||
<!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. Fibonacci 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>Fibonacci sample</h1>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This directory contains an example that computes Fibonacci numbers in several
|
||||
different ways.
|
||||
<br><br>
|
||||
The purpose of the example is to exercise every include file
|
||||
and class in Intel® Threading Building Blocks.
|
||||
Most of the computations are deliberately silly and not expected to
|
||||
show any speedup on multiprocessors.
|
||||
</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="Fibonacci.cpp">Fibonacci.cpp</a>
|
||||
<dd>Source code for 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>fibonacci <i>K</i> [<i>M</i>[:<i>N</i>]] [<i>R</i>]</tt>
|
||||
<dd>Calculates the <i>K</i>-th fibonacci number.
|
||||
<i>M</i> and <i>N</i> are a range of numbers of threads to be used.
|
||||
<i>R</i> is the number of times to repeat the calculation.
|
||||
<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 fibonacci number and the desired number of threads, e.g., <tt>fibonacci 100 4</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 /* Fibonacci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* Fibonacci.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildRule section */
|
||||
C3C58962218C273700DAC94C /* 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 /* Fibonacci */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Fibonacci; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1F593A50B8F042A00073279 /* Fibonacci.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Fibonacci.cpp; path = ../Fibonacci.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 /* Fibonacci */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
);
|
||||
name = Fibonacci;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7795FE84155DC02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1F593A50B8F042A00073279 /* Fibonacci.cpp */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8DD76F6C0486A84900D96B5E /* Fibonacci */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8DD76F620486A84900D96B5E /* Fibonacci */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Fibonacci" */;
|
||||
buildPhases = (
|
||||
8DD76F640486A84900D96B5E /* Sources */,
|
||||
8DD76F660486A84900D96B5E /* Frameworks */,
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
C3C58962218C273700DAC94C /* PBXBuildRule */,
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Fibonacci;
|
||||
productInstallPath = "$(HOME)/bin";
|
||||
productName = Fibonacci;
|
||||
productReference = 8DD76F6C0486A84900D96B5E /* Fibonacci */;
|
||||
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 "fibonacci" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* Fibonacci */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8DD76F620486A84900D96B5E /* Fibonacci */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8DD76F640486A84900D96B5E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1F593A60B8F042A00073279 /* Fibonacci.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)";
|
||||
OTHER_LDFLAGS = (
|
||||
"-m64",
|
||||
"-ltbb_debug",
|
||||
);
|
||||
PRODUCT_NAME = Fibonacci;
|
||||
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 = Fibonacci;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release64;
|
||||
};
|
||||
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
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",
|
||||
);
|
||||
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;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
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 "Fibonacci" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1F593C60B8F0E6E00073279 /* Debug64 */,
|
||||
A1F593C70B8F0E6E00073279 /* Release64 */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release64;
|
||||
};
|
||||
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "fibonacci" */ = {
|
||||
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