[ create a new paste ] login | about

Link: http://codepad.org/YzJc4nQU    [ raw code | fork ]

Evetro - C++, pasted on Jan 10:
/**
 * Parallel Code Count
 * test.cpp
 * Code counting speed testing code.
 */
#include <iostream>
#include <algorithm>
#include <chrono>
#include <type_traits>

#include "random_string.h"
#include "reference.h"
#include "atomic.h"
#include "parallel.h"
#include "std_atomic.h"

using namespace std;

const size_t STRING_SIZE_MAX  = 1u << 27, // maximal size of a random string
             STRING_SIZE_MIN  = 1u << 22, // minimal size of a random string
             ROUNDS           = 10;       // repeat each test ROUNDS times

// returns success (compares result of CountTestFunctor to reference single-threaded implementation)
template <class CountTestFunctor>
bool do_test(volatile double &seconds_sum, const string &s)
{
  int amount[COUNTERS] = {};
  CountTestFunctor F;
  // start timer
  const auto t0 = chrono::high_resolution_clock::now();
  #pragma omp flush (t0)
  F(s, amount);
  #pragma omp flush (amount)
  const auto t1 = chrono::high_resolution_clock::now();
  // stopped timer
  seconds_sum += chrono::duration<double>(t1 - t0).count();
  // check if non-reference
  if (!is_same<CountTestFunctor, ReferenceCountCodes>::value)
  {
    int ref_amount[COUNTERS] = {};
    ReferenceCountCodes()(s, ref_amount);
    return equal(amount, amount + COUNTERS, ref_amount);
  }
  return true;
}

// reports the resulting time (and failures if any) via cout
template <class CountTestFunctor, class SeedGen>
void do_rounds(SeedGen sg, size_t string_size)
{
  volatile double sum; // volatile to prevent some possible compiler optimizations
  // warming up
  do_test<CountTestFunctor>(sum, RandomString<>(sg())(string_size));
  sum = 0.0;
  for (auto r = ROUNDS; r != 0; --r)
  {
    if (!do_test<CountTestFunctor>(sum, RandomString<>(sg())(string_size)))
      cout << "failed ";
  }
  cout << sum / ROUNDS;
}

int main()
{
  cout << "ParallelCodeCount, OpenMP max threads: " << omp_get_max_threads();
  cout << "\n rounds: " << ROUNDS;
  cout << "\n time in seconds\n";

  mt19937 rng;
  uniform_int_distribution<unsigned> seeds;

  for (size_t sz = STRING_SIZE_MAX; sz >= STRING_SIZE_MIN; sz /= 2u)
  {
    cout << "\n string size: " << double(sz) / (1 << 20) << "Mb\n";
    auto sg = [&rng, &seeds]() { return seeds(rng); };
    cout << "reference:   ";
    do_rounds<ReferenceCountCodes>(sg, sz);
    cout << "\natomic:      ";
    do_rounds<AtomicCountCodes>(sg, sz);
    cout << "\nstd::atomic: ";
    do_rounds<StdAtomicCountCodes>(sg, sz);
    cout << "\nparallel:    ";
    do_rounds<ParallelCountCodes>(sg, sz);
    cout << endl;
  }
}


Create a new paste based on this one


Comments: