Skip to content

Instantly share code, notes, and snippets.

@randomphrase
Created December 2, 2014 03:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save randomphrase/aad0615a5ac6696e08f5 to your computer and use it in GitHub Desktop.
Save randomphrase/aad0615a5ac6696e08f5 to your computer and use it in GitHub Desktop.
// -*- mode: c++; c-basic-offset: 4 -*-
#include <boost/timer.hpp>
#include <algorithm>
#include <random>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <stdexcept>
const unsigned WARMUP = 5;
const unsigned ITERATIONS = 10'000'000;
template <std::size_t Size, typename CopyFn>
double TimeArrayCopy(CopyFn copyFn = CopyFn())
{
using namespace std;
char src[Size];
char dst[Size];
// generate random chars for the source array - use constant seed
mt19937 gen(1);
uniform_int_distribution<char> dis('a', 'z');
generate(begin(src), end(src), [&](){ return dis(gen); });
// generate a checksum for the source array (mainly to defeat the optimizer)
static volatile std::size_t src_checksum = accumulate(
begin(src), end(src), 0u, [] (unsigned s, char ch) { return (s + ch) % 256; });
for (unsigned i = 0; i < WARMUP; ++i) {
copyFn(begin(src), end(src), begin(dst));
}
boost::timer time;
for (unsigned i = 0; i < ITERATIONS; ++i) {
copyFn(begin(src), end(src), begin(dst));
}
auto elapsed = time.elapsed();
static volatile std::size_t dst_checksum = accumulate(
begin(dst), end(dst), 0u, [] (unsigned s, char ch) { return (s + ch) % 256; });
if (src_checksum != dst_checksum) {
throw std::runtime_error("checksum mismatch");
}
return elapsed;
}
void Report(const char * name, double baseline, double result)
{
std::cout << std::setw(15) << name << ": "
<< std::fixed << result
<< " (" << std::fixed << result / baseline << " times baseline)" << std::endl;
}
template <std::size_t Size>
void ArrayCopy()
{
auto baseline = TimeArrayCopy<Size>(
[] (const char *begin, const char *end, char *dest) {
while (begin != end) {
*dest++ = *begin++;
}
});
std::cout << "Array copy (size = " << Size << "), baseline : " << baseline << std::endl;
Report("std::memcpy", baseline, TimeArrayCopy<Size>(
[] (const char *begin, const char *end, char *dest) {
std::memcpy(dest, begin, end - begin);
}));
Report("std::memmove", baseline, TimeArrayCopy<Size>(
[] (const char *begin, const char *end, char *dest) {
std::memmove(dest, begin, end - begin);
}));
Report("std::copy", baseline, TimeArrayCopy<Size>(
[] (const char *begin, const char *end, char *dest) {
std::copy(begin, end, dest);
}));
}
int main()
{
std::cout << std::setprecision(8);
try {
ArrayCopy<16>();
ArrayCopy<128>();
ArrayCopy<1024>();
} catch(std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment