Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

View 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

View 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;
}

View File

@@ -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

View 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&reg; 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&reg; 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&reg; 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&reg; 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&nbsp;100&nbsp;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>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -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 */;
}