Il 30/11/17 03:12, Bob ha scritto:
I got no problem up to 30k, too tired to try more :)
Then I changed to c++11 and random generators, please check whether the
generation fits your needs.
Compile with:
g++-6 -std=c++11 -fopenmp -O2 -march=native main.cpp stats.cpp -lgomp
Remember to set something, for Bash you can use:
export OMP_NUM_THREADS=2
export OMP_SCHEDULE=static,1
Riccardo
===== main.cpp =============
#include <vector>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <cstdlib>
#include <omp.h>
#include "stats.hpp"
int main( int argc, char *argv[]) {
try {
int n = 50;
if (argc == 2)
if( (std::istringstream(argv[1]) >> n).fail() || (n < 1) )
throw std::runtime_error("bad input");
std::cerr << "Up to " << n << std::endl;
std::vector< float > x (n);
Sample sample;
std::vector< std::vector<float> > table(n-1);
for ( int ii = 0; ii < n-1; ++ii )
table[ii] = std::vector< float >(8);
double start = omp_get_wtime();
# pragma omp parallel for private(sample) schedule(runtime)
for( int ii = 2; ii < n+1; ++ii ){
if ( (ii % 1000 == 0) )
std::cerr << ".";
sample.randomSample(x, ii);
table[ii-2][0] = sample.computeMean();
table[ii-2][1] = sample.computeMedian();
table[ii-2][2] = sample.computeVar();
table[ii-2][3] = sample.computeStd();
table[ii-2][4] = sample.computeMeanDev();
table[ii-2][5] = sample.computeMedianDev();
table[ii-2][6] = sample.computeSkewness();
table[ii-2][7] = sample.computeMedianSkew();
}
double end = omp_get_wtime();
std::cout << std::endl
<< "Time: " << end -start << "[s]" << std::endl;
}
catch ( std::exception &e ){
std::cerr << e.what() << std::endl;
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
===== stats.cpp (excerpt) =============
#include <random>
void Sample::randomSample(const std::vector<float>& pop, int m)
{
if (m <= 0) {
n = 0;
return;
}
n = m;
int pop_size = pop.size();
// use an index vector - preserve passed vector
std::vector<int> idx(pop_size); // <--------------------------
for (int i = 0; i < pop_size; i++) idx.push_back(i);
// perform pop_size random swaps
std::default_random_engine eng{ static_cast< long unsigned int >
(time(0))};
std::uniform_int_distribution<int> gen( 0, pop_size-1 );
for (int i = 0; i < pop_size; i++) {
// int rndidx = (int)(pop_size*((float)rand()/(float)IMAX));
int rndidx = gen(eng);
int tmp = idx[i];
idx[i] = idx[rndidx];
idx[rndidx] = tmp;
}
// x.clear(); // clear in case something is there
x.resize(n); // <------------------
for (int i = 0; i < n; i++) // x.push_back(pop[idx[i]]);
x[i] = pop[idx[i]]; // <------------------
}