commit
e881ab1bb7
@ -0,0 +1,50 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
CC="/usr/lib/colorgcc/bin/g++"
|
||||||
|
CC_OPTIONS="-Wall -Wextra -pedantic -Wshadow -Weffc++"
|
||||||
|
CC_OPTIMIZE_OPTIONS="-O3 -ffast-math -fwhole-program -fomit-frame-pointer -march=native -m64"
|
||||||
|
CC_LIBS="-lrt"
|
||||||
|
CC_OPENMP="-fopenmp"
|
||||||
|
CC_ITBB="-ltbb"
|
||||||
|
QT_PRO="qtconcurrent.pro"
|
||||||
|
|
||||||
|
echo "CC: $CC"
|
||||||
|
echo "CC options: $CC_OPTIONS"
|
||||||
|
echo "CC optimalization options: $CC_OPTIMIZE_OPTIONS"
|
||||||
|
echo "CC libs: $CC_LIBS"
|
||||||
|
echo "CC openMP options: $CC_OPENMP"
|
||||||
|
echo "CC intel TBB options: $CC_ITBB"
|
||||||
|
|
||||||
|
echo -e "\nSerial algorithms:"
|
||||||
|
for serial in $(ls serial*.cpp)
|
||||||
|
do
|
||||||
|
echo "Compiling $serial ..."
|
||||||
|
$CC $serial $CC_OPTION $CC_OPTIMIZE_OPTIONS $CC_LIBS -o ${serial%\.*}
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\nopenMP algorithms:"
|
||||||
|
for openMP in $(ls openMp*.cpp)
|
||||||
|
do
|
||||||
|
echo "Compiling $openMP ..."
|
||||||
|
$CC $openMP $CC_OPTION $CC_OPTIMIZE_OPTIONS $CC_LIBS $CC_OPENMP -o ${openMP%\.*}
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\nintel TBB algorithms:"
|
||||||
|
for itbb in $(ls itbb*.cpp)
|
||||||
|
do
|
||||||
|
echo "Compiling $itbb ..."
|
||||||
|
$CC $itbb $CC_OPTION $CC_OPTIMIZE_OPTIONS $CC_LIBS $CC_ITBB -o ${itbb%\.*}
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\nQt Concurrent algorithms:"
|
||||||
|
echo "Generating qmake project file ..."
|
||||||
|
|
||||||
|
QT_PRO_CONTENT=$( cat <<EOF
|
||||||
|
config_map {
|
||||||
|
TEMPLATE = app
|
||||||
|
SOURCES = QT_map.cpp
|
||||||
|
TARGET = QT_map
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
echo $QT_PRO_CONTENT > $QT_PRO
|
@ -0,0 +1,122 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time
|
||||||
|
|
||||||
|
#include <tbb/tbb.h>
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
template<int n> class itbbConvolution {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
itbbConvolution(std::vector<float>& output,
|
||||||
|
const std::vector<float>& data,
|
||||||
|
const std::vector<float>& kernel)
|
||||||
|
: m_output(output)
|
||||||
|
, m_data(data)
|
||||||
|
, m_kernel(kernel)
|
||||||
|
{
|
||||||
|
output.resize(data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r) const
|
||||||
|
{
|
||||||
|
float sum;
|
||||||
|
|
||||||
|
const float* __restrict p = &m_data[0] + r.begin();
|
||||||
|
float* __restrict d = &m_output[0]+r.begin();
|
||||||
|
|
||||||
|
float k[n];
|
||||||
|
float c[n];
|
||||||
|
k[0] = m_kernel[0];
|
||||||
|
for (int i = 1; i < n; ++i)
|
||||||
|
{
|
||||||
|
c[i] = p[i-1];
|
||||||
|
k[i] = m_kernel[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, e = r.size()-n-1; i < e ; i += n) {
|
||||||
|
d[i+0] = (c[0] = p[i+0]) * k[0] + c[1]*k[2]+c[2]*k[2]+c[3]*k[3]+c[4]*k[4]+c[5]*k[5]+c[6]*k[6];
|
||||||
|
d[i+1] = (c[6] = p[i+1]) * k[0] + c[0]*k[2]+c[1]*k[2]+c[2]*k[3]+c[3]*k[4]+c[4]*k[5]+c[5]*k[6];
|
||||||
|
d[i+2] = (c[5] = p[i+2]) * k[0] + c[6]*k[2]+c[0]*k[2]+c[1]*k[3]+c[2]*k[4]+c[3]*k[5]+c[4]*k[6];
|
||||||
|
d[i+3] = (c[4] = p[i+3]) * k[0] + c[5]*k[2]+c[6]*k[2]+c[0]*k[3]+c[1]*k[4]+c[2]*k[5]+c[3]*k[6];
|
||||||
|
d[i+4] = (c[3] = p[i+4]) * k[0] + c[4]*k[2]+c[5]*k[2]+c[6]*k[3]+c[0]*k[4]+c[1]*k[5]+c[2]*k[6];
|
||||||
|
d[i+5] = (c[2] = p[i+5]) * k[0] + c[3]*k[2]+c[4]*k[2]+c[5]*k[3]+c[6]*k[4]+c[0]*k[5]+c[1]*k[6];
|
||||||
|
d[i+6] = (c[1] = p[i+6]) * k[0] + c[2]*k[2]+c[3]*k[2]+c[4]*k[3]+c[5]*k[4]+c[6]*k[5]+c[0]*k[6];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r) const
|
||||||
|
{
|
||||||
|
float sum;
|
||||||
|
int middle = m_kernel.size() / 2;
|
||||||
|
|
||||||
|
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += m_data[0] * m_kernel[j+middle];
|
||||||
|
} else if ( i+j > m_data.size()-1 ) {
|
||||||
|
sum += m_data[m_data.size()-1] * m_kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += m_data[i+j] * m_kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<float>& m_output;
|
||||||
|
const std::vector<float>& m_data;
|
||||||
|
const std::vector<float>& m_kernel;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
/*if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = 1;//tbb::task_scheduler_init::default_num_threads();//atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = 300000000;//atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
// initialize random seed
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
// fillup data vector
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
float kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<float> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(float) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<float> output(DATA_SIZE);
|
||||||
|
|
||||||
|
|
||||||
|
itbbConvolution<7> ic(output, data, kernel);
|
||||||
|
|
||||||
|
clock_t start = clock();
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size(), CHUNK_SIZE), ic);
|
||||||
|
|
||||||
|
clock_t end = clock();
|
||||||
|
float elapsed = ((float) (end - start)) / CLOCKS_PER_SEC;
|
||||||
|
std::cout << elapsed << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time
|
||||||
|
|
||||||
|
#include "tbb/task_scheduler_init.h"
|
||||||
|
#include "tbb/blocked_range.h"
|
||||||
|
#include "tbb/parallel_for.h"
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
class itbbConvolution {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
itbbConvolution(std::vector<double>& output,
|
||||||
|
const std::vector<double>& data,
|
||||||
|
const std::vector<double>& kernel)
|
||||||
|
: m_output(output)
|
||||||
|
, m_data(data)
|
||||||
|
, m_kernel(kernel)
|
||||||
|
{
|
||||||
|
output.resize(data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r) const
|
||||||
|
{
|
||||||
|
double sum;
|
||||||
|
int middle = m_kernel.size() / 2;
|
||||||
|
|
||||||
|
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += m_data[0] * m_kernel[j+middle];
|
||||||
|
} else if ( i+j > m_data.size()-1 ) {
|
||||||
|
sum += m_data[m_data.size()-1] * m_kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += m_data[i+j] * m_kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<double>& m_output;
|
||||||
|
const std::vector<double>& m_data;
|
||||||
|
const std::vector<double>& m_kernel;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
// initialize random seed
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
// fillup data vector
|
||||||
|
std::vector<double> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
double kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<double> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(double) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<double> output(DATA_SIZE);
|
||||||
|
|
||||||
|
clock_t start = clock();
|
||||||
|
|
||||||
|
itbbConvolution ic(output, data, kernel);
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size(), CHUNK_SIZE), ic);
|
||||||
|
|
||||||
|
clock_t end = clock();
|
||||||
|
double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
|
||||||
|
std::cout << elapsed << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time
|
||||||
|
|
||||||
|
#include "tbb/task_scheduler_init.h"
|
||||||
|
#include "tbb/blocked_range.h"
|
||||||
|
#include "tbb/parallel_for.h"
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
class itbbConvolution {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
itbbConvolution(std::vector<double>& output,
|
||||||
|
const std::vector<double>& data,
|
||||||
|
const std::vector<double>& kernel)
|
||||||
|
: m_output(output)
|
||||||
|
, m_data(data)
|
||||||
|
, m_kernel(kernel)
|
||||||
|
{
|
||||||
|
output.resize(data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r) const
|
||||||
|
{
|
||||||
|
double sum;
|
||||||
|
int middle = m_kernel.size() / 2;
|
||||||
|
|
||||||
|
// before
|
||||||
|
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += m_data[0] * m_kernel[j+middle];
|
||||||
|
} else if ( i+j > m_data.size()-1 ) {
|
||||||
|
sum += m_data[m_data.size()-1] * m_kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += m_data[i+j] * m_kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += m_data[0] * m_kernel[j+middle];
|
||||||
|
} else if ( i+j > m_data.size()-1 ) {
|
||||||
|
sum += m_data[m_data.size()-1] * m_kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += m_data[i+j] * m_kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// after
|
||||||
|
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += m_data[0] * m_kernel[j+middle];
|
||||||
|
} else if ( i+j > m_data.size()-1 ) {
|
||||||
|
sum += m_data[m_data.size()-1] * m_kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += m_data[i+j] * m_kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<double>& m_output;
|
||||||
|
const std::vector<double>& m_data;
|
||||||
|
const std::vector<double>& m_kernel;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
// initialize random seed
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
// fillup data vector
|
||||||
|
std::vector<double> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
double kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<double> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(double) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<double> output(DATA_SIZE);
|
||||||
|
|
||||||
|
clock_t start = clock();
|
||||||
|
|
||||||
|
itbbConvolution ic(output, data, kernel);
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size(), CHUNK_SIZE), ic);
|
||||||
|
|
||||||
|
clock_t end = clock();
|
||||||
|
double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
|
||||||
|
std::cout << elapsed << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
#include <cfloat> // FLT_MAX
|
||||||
|
|
||||||
|
#include "tbb/task_scheduler_init.h"
|
||||||
|
#include "tbb/blocked_range.h"
|
||||||
|
#include "tbb/parallel_reduce.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class itbbReduce {
|
||||||
|
|
||||||
|
public:
|
||||||
|
float m_min;
|
||||||
|
|
||||||
|
itbbReduce(std::vector<float>& data)
|
||||||
|
: m_data(data)
|
||||||
|
, m_min(FLT_MAX)
|
||||||
|
{}
|
||||||
|
|
||||||
|
itbbReduce(itbbReduce& other, tbb::split)
|
||||||
|
: m_data(other.m_data)
|
||||||
|
, m_min(FLT_MAX)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r)
|
||||||
|
{
|
||||||
|
float min = m_min;
|
||||||
|
for(size_t i = r.begin(); i != r.end(); i++)
|
||||||
|
if ( m_data[i] < min )
|
||||||
|
min = m_data[i];
|
||||||
|
|
||||||
|
m_min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
void join(const itbbReduce& other)
|
||||||
|
{
|
||||||
|
if ( other.m_min < m_min )
|
||||||
|
m_min = other.m_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::vector<float>& m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 4) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE> <CHUNK_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = atoi(argv[3]);
|
||||||
|
|
||||||
|
std::cout << "got: " << NUMBER_OF_THREADS << " " << DATA_SIZE << " " << CHUNK_SIZE << std::endl;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
itbbReduce mif(data);
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, data.size(), CHUNK_SIZE), mif);
|
||||||
|
float min = mif.m_min;
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
|
||||||
|
#include "tbb/task_scheduler_init.h"
|
||||||
|
#include "tbb/blocked_range.h"
|
||||||
|
#include "tbb/parallel_for.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// passing by value and not a reference saves memory read time
|
||||||
|
float modify(float value)
|
||||||
|
{
|
||||||
|
return 13.37 * pow(sqrt(value), log(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class itbbMap {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
itbbMap(std::vector<float>& data)
|
||||||
|
: m_data(data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r) const
|
||||||
|
{
|
||||||
|
for( size_t i = r.begin(); i != r.end(); i++ )
|
||||||
|
m_data[i] = modify(m_data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<float>& m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
itbbMap im(data);
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size(), CHUNK_SIZE), im);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
#include <cfloat> // FLX_MAX
|
||||||
|
|
||||||
|
#include "tbb/task_scheduler_init.h"
|
||||||
|
#include "tbb/blocked_range.h"
|
||||||
|
#include "tbb/parallel_reduce.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class itbbReduce {
|
||||||
|
|
||||||
|
public:
|
||||||
|
float m_min;
|
||||||
|
|
||||||
|
itbbReduce(std::vector<float>& data)
|
||||||
|
: m_data(data)
|
||||||
|
, m_min(FLT_MAX)
|
||||||
|
{}
|
||||||
|
|
||||||
|
itbbReduce(itbbReduce& other, tbb::split)
|
||||||
|
: m_data(other.m_data)
|
||||||
|
, m_min(FLT_MAX)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(const tbb::blocked_range<size_t>& r)
|
||||||
|
{
|
||||||
|
float min = m_min;
|
||||||
|
for(size_t i = r.begin(); i != r.end(); i++)
|
||||||
|
if ( m_data[i] < min )
|
||||||
|
min = m_data[i];
|
||||||
|
|
||||||
|
m_min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
void join(const itbbReduce& other)
|
||||||
|
{
|
||||||
|
if ( other.m_min < m_min )
|
||||||
|
m_min = other.m_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::vector<float>& m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
itbbReduce mif(data);
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, data.size(), CHUNK_SIZE), mif);
|
||||||
|
float min = mif.m_min;
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
|
||||||
|
#include "tbb/task_scheduler_init.h"
|
||||||
|
#include "tbb/parallel_sort.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void itbbSort(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
tbb::parallel_sort(data.begin(), data.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
tbb::task_scheduler_init init(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
itbbSort(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
void openMpConvolution(std::vector<double>& output,
|
||||||
|
const std::vector<double>& input,
|
||||||
|
const std::vector<double>& kernel,
|
||||||
|
const int numberOfThreads,
|
||||||
|
const int chunkSize)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
double sum;
|
||||||
|
int middle = kernel.size() / 2;
|
||||||
|
output.resize(input.size());
|
||||||
|
|
||||||
|
#pragma omp parallel for \
|
||||||
|
default(shared) private(i) \
|
||||||
|
schedule(dynamic, chunkSize) \
|
||||||
|
num_threads(numberOfThreads)
|
||||||
|
|
||||||
|
for (i = 0; i < input.size(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += input[0] * kernel[j+middle];
|
||||||
|
} else if ( i+j > input.size()-1 ) {
|
||||||
|
sum += input[input.size()-1] * kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
// initialize random seed
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
// fillup data vector
|
||||||
|
std::vector<double> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
double kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<double> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(double) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<double> output(DATA_SIZE);
|
||||||
|
|
||||||
|
clock_t start = clock();
|
||||||
|
|
||||||
|
openMpConvolution(output, data, kernel, NUMBER_OF_THREADS, CHUNK_SIZE);
|
||||||
|
|
||||||
|
clock_t end = clock();
|
||||||
|
double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
|
||||||
|
std::cout << elapsed << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// passing by value and not a reference saves memory read time
|
||||||
|
float modify(float value)
|
||||||
|
{
|
||||||
|
return 13.37 * pow(sqrt(value), log(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void openMpMap(std::vector<float>& data,
|
||||||
|
const int numberOfThreads,
|
||||||
|
const int chunkSize)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
#pragma omp parallel for \
|
||||||
|
default(shared) private(i) \
|
||||||
|
schedule(dynamic, chunkSize) \
|
||||||
|
num_threads(numberOfThreads)
|
||||||
|
|
||||||
|
for (i = 0; i < data.size(); i++)
|
||||||
|
data[i] = modify(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
openMpMap(data, NUMBER_OF_THREADS, CHUNK_SIZE);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
void sample_qsort(float* begin, float* end) { ... }
|
||||||
|
|
||||||
|
void sample_qsort_serial(float* begin, float* end) { ... }
|
||||||
|
|
||||||
|
void sample_qsort_adaptive(float* begin, float* end, const long nthreshold)
|
||||||
|
{
|
||||||
|
if (begin != end) {
|
||||||
|
// parition ...
|
||||||
|
if (end - begin + 1 <= nthreshold) {
|
||||||
|
sample_qsort_serial(begin, middle);
|
||||||
|
sample_qsort_serial(++middle, ++end);
|
||||||
|
} else {
|
||||||
|
#pragma omp task
|
||||||
|
sample_qsort_adaptive(begin, middle, nthreshold);
|
||||||
|
#pragma omp task
|
||||||
|
sample_qsort_adaptive(++middle, ++end, nthreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sample_qsort_adaptive(float* begin, float* end)
|
||||||
|
{
|
||||||
|
long nthreshold = ceil(sqrt(end - begin + 1)) / 2;
|
||||||
|
#pragma omp parallel
|
||||||
|
#pragma omp single nowait
|
||||||
|
sample_qsort_adaptive(begin, end, nthreshold);
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
// from http://berenger.eu/blog/2011/10/06/c-openmp-a-shared-memory-quick-sort-with-openmp-tasks-example-source-code/
|
||||||
|
|
||||||
|
|
||||||
|
template <class NumType>
|
||||||
|
inline void Swap(NumType& value, NumType& other)
|
||||||
|
{
|
||||||
|
NumType temp = value;
|
||||||
|
value = other;
|
||||||
|
other = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
long QsPartition(SortType outputArray[], long left, long right)
|
||||||
|
{
|
||||||
|
const long part = right;
|
||||||
|
Swap(outputArray[part],outputArray[left + (right - left ) / 2]);
|
||||||
|
const SortType partValue = outputArray[part];
|
||||||
|
--right;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
while(outputArray[left] < partValue)
|
||||||
|
++left;
|
||||||
|
|
||||||
|
while(right >= left && partValue <= outputArray[right])
|
||||||
|
--right;
|
||||||
|
|
||||||
|
if(right < left)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Swap(outputArray[left],outputArray[right]);
|
||||||
|
++left;
|
||||||
|
--right;
|
||||||
|
}
|
||||||
|
|
||||||
|
Swap(outputArray[part],outputArray[left]);
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
void QsSequential(SortType array[], const long left, const long right)
|
||||||
|
{
|
||||||
|
if (left < right) {
|
||||||
|
const long part = QsPartition(array, left, right);
|
||||||
|
QsSequential(array,part + 1,right);
|
||||||
|
QsSequential(array,left,part - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
void QuickSortOmpTask(SortType array[], const long left, const long right, const int deep)
|
||||||
|
{
|
||||||
|
if (left < right) {
|
||||||
|
if (deep) {
|
||||||
|
const long part = QsPartition(array, left, right);
|
||||||
|
|
||||||
|
#pragma omp task
|
||||||
|
QuickSortOmpTask(array,part + 1,right, deep - 1);
|
||||||
|
#pragma omp task
|
||||||
|
QuickSortOmpTask(array,left,part - 1, deep - 1);
|
||||||
|
} else {
|
||||||
|
const long part = QsPartition(array, left, right);
|
||||||
|
QsSequential(array,part + 1,right);
|
||||||
|
QsSequential(array,left,part - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
void QuickSortOmp(SortType array[], const long size)
|
||||||
|
{
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
#pragma omp single nowait
|
||||||
|
{
|
||||||
|
QuickSortOmpTask(array, 0, size - 1 , 15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
//#include <algorithm> // min, min_element
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
#include <cfloat> // FLT_MAX
|
||||||
|
|
||||||
|
#include <omp.h> // omp_get_thread_num()
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int openMpReduce(std::vector<float>& data,
|
||||||
|
const int numberOfThreads,
|
||||||
|
const int chunkSize)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
std::vector<float> separate_results(numberOfThreads, FLT_MAX);
|
||||||
|
|
||||||
|
#pragma omp parallel \
|
||||||
|
default(shared) private(i) \
|
||||||
|
num_threads(numberOfThreads)
|
||||||
|
{
|
||||||
|
int threadId = omp_get_thread_num();
|
||||||
|
|
||||||
|
#pragma omp for \
|
||||||
|
schedule(dynamic, chunkSize)
|
||||||
|
|
||||||
|
for (i = 0; i < data.size(); i++)
|
||||||
|
if (separate_results[threadId] < data[i])
|
||||||
|
separate_results[threadId] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// serial reduce
|
||||||
|
float min(FLT_MAX);
|
||||||
|
for (i = 0; i < numberOfThreads; i++)
|
||||||
|
if (separate_results[i] < min)
|
||||||
|
min = separate_results[i];
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
float min = openMpReduce(data, NUMBER_OF_THREADS, CHUNK_SIZE);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
#include <parallel/algorithm> // parallel sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
|
||||||
|
#include <omp.h> // omp_set_num_threads
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void openMpSort(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
__gnu_parallel::sort(data.begin(), data.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
// const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
omp_set_num_threads(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
openMpSort(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
|
||||||
|
#include <omp.h> // omp_set_num_threads
|
||||||
|
|
||||||
|
#include "openMp_quicksort2.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void openMpSort(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
sample_qsort_adaptive(data.data(), data.data() + data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
// const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
omp_set_num_threads(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
openMpSort(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
|
||||||
|
#include <omp.h> // omp_set_num_threads
|
||||||
|
|
||||||
|
#include "openMp_quicksort3.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void openMpSort(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
QuickSortOmp(data.data(), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
// const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
omp_set_num_threads(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
openMpSort(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
|
||||||
|
#include <QtCore/QtCore>
|
||||||
|
#include <QtCore/QThreadPool>
|
||||||
|
#include <QtCore/QtConcurrentMap>
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float modify(const float value)
|
||||||
|
{
|
||||||
|
return 13.37 * pow(sqrt(value), log(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QtMap(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
QtConcurrent::blockingMap(data, modify);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
// const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
QThreadPool::globalInstance()->setMaxThreadCount(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
QtMap(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/// from http://berenger.eu/blog/2011/10/06/c-openmp-a-shared-memory-quick-sort-with-openmp-tasks-example-source-code/
|
||||||
|
|
||||||
|
#include <QtCore/QtConcurrentRun>
|
||||||
|
|
||||||
|
|
||||||
|
template <class NumType>
|
||||||
|
inline void Swap(NumType& value, NumType& other)
|
||||||
|
{
|
||||||
|
NumType temp = value;
|
||||||
|
value = other;
|
||||||
|
other = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
long QsPartition(SortType outputArray[], long left, long right)
|
||||||
|
{
|
||||||
|
const long part = right;
|
||||||
|
Swap(outputArray[part],outputArray[left + (right - left ) / 2]);
|
||||||
|
const SortType partValue = outputArray[part];
|
||||||
|
--right;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
while(outputArray[left] < partValue)
|
||||||
|
++left;
|
||||||
|
|
||||||
|
while(right >= left && partValue <= outputArray[right])
|
||||||
|
--right;
|
||||||
|
|
||||||
|
if(right < left)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Swap(outputArray[left],outputArray[right]);
|
||||||
|
++left;
|
||||||
|
--right;
|
||||||
|
}
|
||||||
|
|
||||||
|
Swap(outputArray[part],outputArray[left]);
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
void QsSequential(SortType array[], const long left, const long right)
|
||||||
|
{
|
||||||
|
if (left < right) {
|
||||||
|
const long part = QsPartition(array, left, right);
|
||||||
|
QsSequential(array,part + 1,right);
|
||||||
|
QsSequential(array,left,part - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class SortType>
|
||||||
|
void QuickSortTask (SortType array[], const long left, const long right, const int deep)
|
||||||
|
{
|
||||||
|
if (left < right) {
|
||||||
|
if (deep) {
|
||||||
|
const long part = QsPartition(array, left, right);
|
||||||
|
|
||||||
|
QtConcurrent::run(QuickSortTask<SortType>, array, part + 1, right, deep - 1);
|
||||||
|
QtConcurrent::run(QuickSortTask<SortType>, array, left, part - 1, deep - 1);
|
||||||
|
} else {
|
||||||
|
const long part = QsPartition(array, left, right);
|
||||||
|
QsSequential(array,part + 1,right);
|
||||||
|
QsSequential(array,left,part - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // min_element
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
#include <cfloat> // FLX_MAX
|
||||||
|
|
||||||
|
#include <QtCore/QtCore>
|
||||||
|
#include <QtCore/QThreadPool>
|
||||||
|
#include <QtCore/QtConcurrentRun>
|
||||||
|
#include <QtCore/QFutureSynchronizer>
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void findLocalMinimum(const std::vector<float>::const_iterator begin,
|
||||||
|
const std::vector<float>::const_iterator end,
|
||||||
|
float *result)
|
||||||
|
{
|
||||||
|
float min(FLT_MAX);
|
||||||
|
for(std::vector<float>::const_iterator it = begin; it != end; ++it)
|
||||||
|
if (*it < min)
|
||||||
|
min = *it;
|
||||||
|
|
||||||
|
*result = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float QtReduce(std::vector<float>& data,
|
||||||
|
const int numberOfThreads,
|
||||||
|
const int chunkSize)
|
||||||
|
{
|
||||||
|
std::vector<float> separate_results(numberOfThreads, FLT_MAX);
|
||||||
|
QFutureSynchronizer<void> synchronizer;
|
||||||
|
|
||||||
|
for(int i = 0; i < numberOfThreads; i++)
|
||||||
|
synchronizer.addFuture(QtConcurrent::run(findLocalMinimum,
|
||||||
|
data.begin()+i*chunkSize,
|
||||||
|
data.begin()+(i+1)*chunkSize,
|
||||||
|
separate_results.data()+i));
|
||||||
|
|
||||||
|
synchronizer.waitForFinished();
|
||||||
|
|
||||||
|
// serial reduce
|
||||||
|
float min(FLT_MAX);
|
||||||
|
for (int i = 0; i < numberOfThreads; i++)
|
||||||
|
if (separate_results[i] < min)
|
||||||
|
min = separate_results[i];
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
QThreadPool::globalInstance()->setMaxThreadCount(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
float min = QtReduce(data, NUMBER_OF_THREADS, CHUNK_SIZE);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
|
||||||
|
#include <QtCore/QtCore>
|
||||||
|
#include <QtCore/QThreadPool>
|
||||||
|
#include <QtCore/QtConcurrentRun>
|
||||||
|
|
||||||
|
#include "qt_quicksort.h"
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QtSort(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
QtConcurrent::run(QuickSortTask<float>, data.data(), 0, data.size() - 1, 6);
|
||||||
|
QThreadPool::globalInstance()->waitForDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
QThreadPool::globalInstance()->setMaxThreadCount(NUMBER_OF_THREADS);
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
QtSort(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
config_map { TEMPLATE = app SOURCES = QT_map.cpp TARGET = QT_map }
|
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
MAP_DATASIZE=6000000
|
||||||
|
THREADS="10"
|
||||||
|
ITERATIONS="3"
|
||||||
|
|
||||||
|
echo "Thread numbers: $THREAD_NUMBERS"
|
||||||
|
echo "Iteration number of each binary: $ITERATIONS"
|
||||||
|
echo "Map data size: $MAP_DATASIZE"
|
||||||
|
|
||||||
|
|
||||||
|
echo -e "\nsort algorithms:"
|
||||||
|
for map in $(ls *_sort* | grep -v '\.cpp')
|
||||||
|
do
|
||||||
|
echo "Running $map ..."
|
||||||
|
for threadnum in `seq 1 $THREADS`
|
||||||
|
do
|
||||||
|
echo "Number of threads: $threadnum"
|
||||||
|
for i in `seq 1 $ITERATIONS`
|
||||||
|
do
|
||||||
|
./$map $threadnum $MAP_DATASIZE
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
MILLION="1000000"
|
||||||
|
DATASIZE=100
|
||||||
|
THREADS=10
|
||||||
|
ITERATIONS=3
|
||||||
|
GRAINSIZE_POWEROFTEN="8"
|
||||||
|
|
||||||
|
echo "Thread numbers: 1 .. $THREADS"
|
||||||
|
echo "Iteration number of each binary: $ITERATIONS"
|
||||||
|
echo "Map data size: " $DATASIZE
|
||||||
|
|
||||||
|
let subba=10^7
|
||||||
|
./itbb_grainsize $THREADS $DATASIZE pow(10,3)
|
||||||
|
|
||||||
|
#for grainsize in `seq 0 $GRAINSIZE_POWEROFTEN`
|
||||||
|
#do
|
||||||
|
# echo "Grainsize: 10^$grainsize"
|
||||||
|
# for threadnum in `seq 1 $THREADS`
|
||||||
|
# do
|
||||||
|
# echo "Number of threads: $threadnum"
|
||||||
|
# for i in `seq 1 $ITERATIONS`
|
||||||
|
# do
|
||||||
|
# ./itbb_grainsize $threadnum $DATASIZE 10^$grainsize
|
||||||
|
# done
|
||||||
|
# done
|
||||||
|
#done
|
@ -0,0 +1,85 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serialConvolution(std::vector<float>& output,
|
||||||
|
const std::vector<float>& input,
|
||||||
|
const std::vector<float>& kernel)
|
||||||
|
{
|
||||||
|
float sum;
|
||||||
|
int middle = kernel.size() / 2;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input.size(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += input[0] * kernel[j+middle];
|
||||||
|
} else if ( i+j > input.size()-1 ) {
|
||||||
|
sum += input[input.size()-1] * kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
float kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<float> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(float) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<float> output(DATA_SIZE);
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
serialConvolution(output, data, kernel);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @todo rewrite it
|
||||||
|
void serialConvolution(std::vector<float>& output,
|
||||||
|
const std::vector<float>& input,
|
||||||
|
const std::vector<float>& kernel)
|
||||||
|
{
|
||||||
|
float sum;
|
||||||
|
int middle = kernel.size() / 2;
|
||||||
|
|
||||||
|
// before
|
||||||
|
for (size_t i = 0; i < middle; i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += input[0] * kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = middle; i < input.size()-middle; i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// after
|
||||||
|
for (size_t i = input.size()-middle; i < input.size(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( i+j > input.size()-1 ) {
|
||||||
|
sum += input[input.size()-1] * kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
float kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<float> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(float) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<float> output(DATA_SIZE);
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
serialConvolution(output, data, kernel);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @todo rewrite it
|
||||||
|
void serialConvolution(std::vector<float>& output,
|
||||||
|
const std::vector<float>& input,
|
||||||
|
const std::vector<float>& kernel)
|
||||||
|
{
|
||||||
|
float sum;
|
||||||
|
int middle = kernel.size() / 2;
|
||||||
|
|
||||||
|
// before
|
||||||
|
for (size_t i = 0; i < middle; i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( (int)i+j < 0 ) {
|
||||||
|
sum += input[0] * kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unfolded loop
|
||||||
|
const float* p = &input[0];
|
||||||
|
float* d = &output[0];
|
||||||
|
size_t n = kernel.size();
|
||||||
|
float k[n];
|
||||||
|
float c[n];
|
||||||
|
k[0] = kernel[0];
|
||||||
|
for (int i = 1; i < n; ++i)
|
||||||
|
{
|
||||||
|
c[i] = p[i-1];
|
||||||
|
k[i] = kernel[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, e = input.size()-n-1; i < e ; i += n) {
|
||||||
|
d[i+0] = (c[0] = p[i+0]) * k[0] + c[1]*k[2]+c[2]*k[2]+c[3]*k[3]+c[4]*k[4]+c[5]*k[5]+c[6]*k[6];
|
||||||
|
d[i+1] = (c[6] = p[i+1]) * k[0] + c[0]*k[2]+c[1]*k[2]+c[2]*k[3]+c[3]*k[4]+c[4]*k[5]+c[5]*k[6];
|
||||||
|
d[i+2] = (c[5] = p[i+2]) * k[0] + c[6]*k[2]+c[0]*k[2]+c[1]*k[3]+c[2]*k[4]+c[3]*k[5]+c[4]*k[6];
|
||||||
|
d[i+3] = (c[4] = p[i+3]) * k[0] + c[5]*k[2]+c[6]*k[2]+c[0]*k[3]+c[1]*k[4]+c[2]*k[5]+c[3]*k[6];
|
||||||
|
d[i+4] = (c[3] = p[i+4]) * k[0] + c[4]*k[2]+c[5]*k[2]+c[6]*k[3]+c[0]*k[4]+c[1]*k[5]+c[2]*k[6];
|
||||||
|
d[i+5] = (c[2] = p[i+5]) * k[0] + c[3]*k[2]+c[4]*k[2]+c[5]*k[3]+c[6]*k[4]+c[0]*k[5]+c[1]*k[6];
|
||||||
|
d[i+6] = (c[1] = p[i+6]) * k[0] + c[2]*k[2]+c[3]*k[2]+c[4]*k[3]+c[5]*k[4]+c[6]*k[5]+c[0]*k[6];
|
||||||
|
}
|
||||||
|
|
||||||
|
// after
|
||||||
|
for (size_t i = input.size()-middle; i < input.size(); i++) {
|
||||||
|
sum = 0;
|
||||||
|
for (int j = -middle; j <= middle; j++)
|
||||||
|
if ( i+j > input.size()-1 ) {
|
||||||
|
sum += input[input.size()-1] * kernel[j+middle];
|
||||||
|
} else {
|
||||||
|
sum += input[i+j] * kernel[j+middle];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
|
||||||
|
// the kernel for the gaussian smooth
|
||||||
|
float kernelArray[7] = { 0.06, 0.061, 0.242, 0.383, 0.242, 0.061, 0.06 };
|
||||||
|
std::vector<float> kernel (kernelArray, kernelArray + sizeof(kernelArray) / sizeof(float) );
|
||||||
|
|
||||||
|
// the convolution is not in-place, the result is stored in output
|
||||||
|
std::vector<float> output(DATA_SIZE);
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
serialConvolution(output, data, kernel);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
#include <cmath> // pow, sqrt, log
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// passing by value and not a reference saves memory read time
|
||||||
|
float modify(float value)
|
||||||
|
{
|
||||||
|
return 13.37 * pow(sqrt(value), log(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serialMap(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < data.size(); i++)
|
||||||
|
modify(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
serialMap(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
#include <cfloat> // FLT_MAX
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// not a reduce actually, just a sequential get minimum value
|
||||||
|
float serialReduce(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
float min(FLT_MAX);
|
||||||
|
for (size_t i = 0; i < data.size(); i++)
|
||||||
|
if (data[i] < min)
|
||||||
|
min = data[i];
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
float min = serialReduce(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // sort
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // time, timespec, clock_gettime
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serialSort(std::vector<float>& data)
|
||||||
|
{
|
||||||
|
std::sort(data.begin(), data.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
serialSort(data);
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cstdlib> // srand, rand, atoi
|
||||||
|
#include <ctime> // timespec, clock_gettime
|
||||||
|
// #include <sys/time.h>
|
||||||
|
// #include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
const int RANDOM_MAX = 1000;
|
||||||
|
const int RANDOM_MIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
timespec diff(timespec start, timespec end)
|
||||||
|
{
|
||||||
|
timespec temp;
|
||||||
|
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||||
|
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Usage: " << argv[0] << " <NUMBER_OF_THREADS> <DATA_SIZE>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUMBER_OF_THREADS = atoi(argv[1]);
|
||||||
|
const int DATA_SIZE = atoi(argv[2]);
|
||||||
|
const int CHUNK_SIZE = DATA_SIZE / NUMBER_OF_THREADS;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
std::vector<float> data(DATA_SIZE);
|
||||||
|
for (int i = 0; i < DATA_SIZE; i++)
|
||||||
|
data[i] = rand() % RANDOM_MAX + RANDOM_MIN;
|
||||||
|
|
||||||
|
timespec startTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
||||||
|
|
||||||
|
/// DO STUFF, use: data, NUMBER_OF_THREADS, CHUNK_SIZE
|
||||||
|
|
||||||
|
timespec endTime;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
||||||
|
timespec timeDiff = diff(startTime, endTime);
|
||||||
|
std::cout << timeDiff.tv_sec << "." << timeDiff.tv_nsec << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
QT_PRO="qtconcurrent.pro"
|
||||||
|
|
||||||
|
echo -e "\nQt Concurrent algorithms:"
|
||||||
|
echo "Generating qmake project file ..."
|
||||||
|
|
||||||
|
QT_PRO_CONTENT=""
|
||||||
|
|
||||||
|
# QT_PRO_CONTENT=$( cat <<EOF
|
||||||
|
#read -d '' QT_PRO_CONTENT <<"EOF"
|
||||||
|
cat > $QT_PRO <<_EOF_
|
||||||
|
config_map {
|
||||||
|
TEMPLATE = app
|
||||||
|
QT = core
|
||||||
|
CONFIG = console
|
||||||
|
CXXFLAGS = -Wextra
|
||||||
|
|
||||||
|
|
||||||
|
TARGET = QT_map
|
||||||
|
SOURCES = QT_map.cpp
|
||||||
|
}
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
|
||||||
|
echo -e $QT_PRO_CONTENT
|
||||||
|
|
Loading…
Reference in new issue