232 lines
6.0 KiB
C++
232 lines
6.0 KiB
C++
#include <algorithm>
|
|
#include <iostream>
|
|
#include <iterator>
|
|
#include <sstream>
|
|
|
|
#include "common.h"
|
|
|
|
constexpr std::size_t K = 1'000;
|
|
|
|
std::size_t pfor::ParallelForParameters::nThreads{1};
|
|
|
|
struct Arguments {
|
|
std::size_t arraySize;
|
|
std::string method;
|
|
std::size_t sample;
|
|
};
|
|
|
|
Arguments processCLA(int argc, char** argv) {
|
|
if(argc < 4) {
|
|
std::cerr << "Usage: " << *argv << " N method #sample [nThreads]" << std::endl;
|
|
std::cerr << " N: array size (1..1000000)" << std::endl;
|
|
std::cerr << " method: {seq, omp, gen_omp, gen_thread}" << std::endl;
|
|
std::cerr << " #sample: {0: full sequential, 1: full parallel, 2: mixed sequential/parallel}" << std::endl;
|
|
std::cerr << " nThreads: defaults to 1" << std::endl;
|
|
std::exit(1);
|
|
}
|
|
|
|
Arguments args;
|
|
|
|
{
|
|
std::istringstream iss{argv[1]};
|
|
iss >> args.arraySize;
|
|
}
|
|
args.method = std::string{argv[2]};
|
|
{
|
|
std::istringstream iss{argv[3]};
|
|
iss >> args.sample;
|
|
}
|
|
|
|
if(argc >= 5) {
|
|
std::istringstream iss{argv[4]};
|
|
iss >> pfor::ParallelForParameters::nThreads;
|
|
}
|
|
|
|
|
|
if(args.arraySize < 1 || args.arraySize > 10000000) {
|
|
std::cerr << "N out of bounds" << std::endl;
|
|
std::exit(1);
|
|
}
|
|
|
|
if(args.method != "seq" && args.method != "omp" && args.method != "gen_omp" && args.method != "gen_thread") {
|
|
std::cerr << "method out of bounds" << std::endl;
|
|
std::exit(1);
|
|
}
|
|
|
|
if(args.sample > 2) {
|
|
std::cerr << "#sample out of bounds" << std::endl;
|
|
std::exit(1);
|
|
}
|
|
|
|
if(args.method == "omp" && args.sample == 0) {
|
|
std::cerr << "incoherent method/#sample" << std::endl;
|
|
std::exit(1);
|
|
}
|
|
|
|
return args;
|
|
}
|
|
|
|
using T = int;
|
|
|
|
int main(int argc, char **argv) {
|
|
Arguments args = processCLA(argc, argv);
|
|
long const N = args.arraySize;
|
|
|
|
OPERAND(T, a0, N, i++);
|
|
OPERAND(T, a1, N, i++);
|
|
OPERAND(T, a2, N, i++);
|
|
OPERAND(T, a3, N, i++);
|
|
OPERAND(T, a4, N, i++);
|
|
OPERAND(T, a5, N, i++);
|
|
OPERAND(T, a6, N, i++);
|
|
OPERAND(T, a7, N, i++);
|
|
|
|
if(args.sample == 0) {
|
|
/*
|
|
* Sample 0: sequential
|
|
*/
|
|
// arraysPrinter(K, N, a0, a1, a2, a5);
|
|
|
|
if(args.method == "seq") {
|
|
BENCH(K)
|
|
for(long i = 0; i < N-1; ++i) {
|
|
a0_[i] = a0_[i+1] + a1_[i] * a2_[i];
|
|
a1_[i] = a1_[i+1] + a2_[i] * a3_[i];
|
|
a2_[i] = a2_[i+1] + a3_[i] * a4_[i];
|
|
a5_[i] = a5_[i+1] + a6_[i] * a7_[i];
|
|
}
|
|
END_BENCH();
|
|
} else if(args.method == "gen_omp") {
|
|
BENCH(K)
|
|
pfor::parallelFor<pfor::ForLoopOMP>(pfor::Range{0, N-1}, [&](pfor::Index i) {
|
|
return
|
|
a0[i] = a0[i+_<1>] + a1[i] * a2[i],
|
|
a1[i] = a1[i+_<1>] + a2[i] * a3[i],
|
|
a2[i] = a2[i+_<1>] + a3[i] * a4[i],
|
|
a5[i] = a5[i+_<1>] + a6[i] * a7[i];
|
|
});
|
|
END_BENCH();
|
|
} else if(args.method == "gen_thread") {
|
|
BENCH(K)
|
|
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, N-1}, [&](pfor::Index i) {
|
|
return
|
|
a0[i] = a0[i+_<1>] + a1[i] * a2[i],
|
|
a1[i] = a1[i+_<1>] + a2[i] * a3[i],
|
|
a2[i] = a2[i+_<1>] + a3[i] * a4[i],
|
|
a5[i] = a5[i+_<1>] + a6[i] * a7[i];
|
|
});
|
|
END_BENCH();
|
|
}
|
|
|
|
// arraysPrinter(K, N, a0, a1, a2, a5);
|
|
} else if(args.sample == 1) {
|
|
/*
|
|
* Sample 1: parallel
|
|
*/
|
|
if(args.method == "seq") {
|
|
BENCH(K)
|
|
for(long i = 0; i < N; ++i) {
|
|
a0_[i] = a0_[i] + a1_[i] * a2_[i];
|
|
a1_[i] = a1_[i] + a2_[i] * a3_[i];
|
|
a2_[i] = a2_[i] + a3_[i] * a4_[i];
|
|
a5_[i] = a5_[i] + a6_[i] * a7_[i];
|
|
}
|
|
END_BENCH();
|
|
} else if(args.method == "omp") {
|
|
BENCH(K)
|
|
#pragma omp parallel for num_threads(pfor::ParallelForParameters::nThreads)
|
|
for(long i = 0; i < N; ++i) {
|
|
a0_[i] = a0_[i] + a1_[i] * a2_[i];
|
|
a1_[i] = a1_[i] + a2_[i] * a3_[i];
|
|
a2_[i] = a2_[i] + a3_[i] * a4_[i];
|
|
a5_[i] = a5_[i] + a6_[i] * a7_[i];
|
|
}
|
|
END_BENCH();
|
|
} else if(args.method == "gen_omp") {
|
|
BENCH(K)
|
|
pfor::parallelFor<pfor::ForLoopOMP>(pfor::Range{0, N}, [&](pfor::Index i) {
|
|
return
|
|
a0[i] = a0[i] + a1[i] * a2[i],
|
|
a1[i] = a1[i] + a2[i] * a3[i],
|
|
a2[i] = a2[i] + a3[i] * a4[i],
|
|
a5[i] = a5[i] + a6[i] * a7[i];
|
|
});
|
|
END_BENCH();
|
|
} else if(args.method == "gen_thread") {
|
|
BENCH(K)
|
|
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, N}, [&](pfor::Index i) {
|
|
return
|
|
a0[i] = a0[i] + a1[i] * a2[i],
|
|
a1[i] = a1[i] + a2[i] * a3[i],
|
|
a2[i] = a2[i] + a3[i] * a4[i],
|
|
a5[i] = a5[i] + a6[i] * a7[i];
|
|
});
|
|
END_BENCH();
|
|
}
|
|
} else if(args.sample == 2) {
|
|
/*
|
|
* Sample 2: mixed sequential and parallel
|
|
*/
|
|
// arraysPrinter(K, N, a0, a1, a2, a3, a4, a5, a6, a7);
|
|
|
|
if(args.method == "seq") {
|
|
BENCH(K)
|
|
for(long i = 0; i < N-1; ++i) {
|
|
a0_[i] = a0_[i] + a1_[i] * a2_[i];
|
|
a1_[i] = a1_[i] + a2_[i] * a3_[i];
|
|
}
|
|
for(long i = 0; i < N-1; ++i) {
|
|
a4_[i] = a4_[i+1] + a5_[i] * a7_[i];
|
|
a5_[i] = a5_[i+1] + a6_[i] * a7_[i];
|
|
}
|
|
END_BENCH();
|
|
} else if(args.method == "omp") {
|
|
BENCH(K)
|
|
#pragma omp parallel for num_threads(pfor::ParallelForParameters::nThreads)
|
|
for(long i = 0; i < N-1; ++i) {
|
|
a0_[i] = a0_[i] + a1_[i] * a2_[i];
|
|
a1_[i] = a1_[i] + a2_[i] * a3_[i];
|
|
}
|
|
// Sequential
|
|
for(long i = 0; i < N-1; ++i) {
|
|
a4_[i] = a4_[i+1] + a5_[i] * a7_[i];
|
|
a5_[i] = a5_[i+1] + a6_[i] * a7_[i];
|
|
}
|
|
END_BENCH();
|
|
} else if(args.method == "gen_omp") {
|
|
BENCH(K)
|
|
pfor::parallelFor<pfor::ForLoopOMP>(pfor::Range{0, N-1}, [&](pfor::Index i) {
|
|
return
|
|
a0[i] = a0[i] + a1[i] * a2[i],
|
|
a1[i] = a1[i] + a2[i] * a3[i],
|
|
a4[i] = a4[i+_<1>] + a5[i] * a7[i],
|
|
a5[i] = a5[i+_<1>] + a6[i] * a7[i];
|
|
});
|
|
END_BENCH();
|
|
} else if(args.method == "gen_thread") {
|
|
BENCH(K)
|
|
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, N-1}, [&](pfor::Index i) {
|
|
return
|
|
a0[i] = a0[i] + a1[i] * a2[i],
|
|
a1[i] = a1[i] + a2[i] * a3[i],
|
|
a4[i] = a4[i+_<1>] + a5[i] * a7[i],
|
|
a5[i] = a5[i+_<1>] + a6[i] * a7[i];
|
|
});
|
|
END_BENCH();
|
|
}
|
|
|
|
// arraysPrinter(K, N, a0, a1, a2, a3, a4, a5, a6, a7);
|
|
}
|
|
|
|
if(rand()==rand()) arraysPrinter(1ul, N, a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
|
|
|
|
END_OPERAND(a0);
|
|
END_OPERAND(a1);
|
|
END_OPERAND(a2);
|
|
END_OPERAND(a3);
|
|
END_OPERAND(a4);
|
|
END_OPERAND(a5);
|
|
END_OPERAND(a6);
|
|
END_OPERAND(a7);
|
|
}
|