// parloop_cpp0x_openmp.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include #include #include #include #ifndef _OPENMP #error OpenMP support required! #endif #include double compute(double val, const int numiterations) { for (int i = 0; i < numiterations; i++) { val = std::sin(val) * std::cos(val); } return val; } void run_serial(int iNumRepetitions, int iNumElements, int iNumIterations) { std::vector vec(iNumElements); double dBest = std::numeric_limits::max(); int iBest = 0; double dWorst = std::numeric_limits::min(); int iWorst = 0; double dStart, dEnd; for (int rep = 0; rep < iNumRepetitions; rep++) { dStart = omp_get_wtime(); for (int i = 0; i < iNumElements; i++) { vec[i] = compute(vec[i], iNumIterations); } dEnd = omp_get_wtime(); double dTime = dEnd - dStart; if (dBest > dTime) { dBest = dTime; iBest = rep; } if (dWorst < dTime) { dWorst = dTime; iWorst = rep; } } std::cout << "Results of 'run_serial':" << std::endl; std::cout << " +best: " << dBest << " in repetition " << iBest << std::endl; std::cout << " -worst: " << dWorst << " in repetition " << iWorst << std::endl; std::cout << std::endl; } void run_openmp_for(int iNumRepetitions, int iNumElements, int iNumIterations) { std::vector vec(iNumElements); double dBest = std::numeric_limits::max(); int iBest = 0; double dWorst = std::numeric_limits::min(); int iWorst = 0; double dStart, dEnd; for (int rep = 0; rep < iNumRepetitions; rep++) { dStart = omp_get_wtime(); #pragma omp parallel for shared(iNumElements, vec, iNumIterations) for (int i = 0; i < iNumElements; i++) { vec[i] = compute(vec[i], iNumIterations); } dEnd = omp_get_wtime(); double dTime = dEnd - dStart; if (dBest > dTime) { dBest = dTime; iBest = rep; } if (dWorst < dTime) { dWorst = dTime; iWorst = rep; } } std::cout << "Results of 'run_openmp_for':" << std::endl; std::cout << " +best: " << dBest << " in repetition " << iBest << std::endl; std::cout << " -worst: " << dWorst << " in repetition " << iWorst << std::endl; std::cout << std::endl; } template void omp_pfor(int start, int end, F x) { #pragma omp parallel for for(int __i = start; __i < end; __i++) { x(__i); } } void run_pfor(int iNumRepetitions, int iNumElements, int iNumIterations) { std::vector vec(iNumElements); double dBest = std::numeric_limits::max(); int iBest = 0; double dWorst = std::numeric_limits::min(); int iWorst = 0; double dStart, dEnd; for (int rep = 0; rep < iNumRepetitions; rep++) { dStart = omp_get_wtime(); omp_pfor (0, iNumElements, [&](int i) { vec[i] = compute(vec[i], iNumIterations); }); dEnd = omp_get_wtime(); double dTime = dEnd - dStart; if (dBest > dTime) { dBest = dTime; iBest = rep; } if (dWorst < dTime) { dWorst = dTime; iWorst = rep; } } std::cout << "Results of 'run_ompfor':" << std::endl; std::cout << " +best: " << dBest << " in repetition " << iBest << std::endl; std::cout << " -worst: " << dWorst << " in repetition " << iWorst << std::endl; std::cout << std::endl; } void printUsage() { std::cout << "Usage: parloop num_repetitions num_elements num_iterations" << std::endl; std::cout << " - num_repetitions: number of test repetitions" << std::endl; std::cout << " - num_elements: dimension of work array" << std::endl; std::cout << " - num_iterations: number of iterations per element" << std::endl; std::cout << std::endl; } int main(int argc, char* argv[]) { if (argc != 4) { printUsage(); return EXIT_FAILURE; } int iNumRepetitions = atoi(argv[1]); int iNumElements = atoi(argv[2]); int iNumIterations = atoi(argv[3]); run_serial(iNumRepetitions, iNumElements, iNumIterations); run_openmp_for(iNumRepetitions, iNumElements, iNumIterations); run_pfor(iNumRepetitions, iNumElements, iNumIterations); return EXIT_SUCCESS; }