Skip to content

Instantly share code, notes, and snippets.

@makotoshimazu
Created February 17, 2015 14:21
Show Gist options
  • Save makotoshimazu/f6d8bd42b0c1df01bbfe to your computer and use it in GitHub Desktop.
Save makotoshimazu/f6d8bd42b0c1df01bbfe to your computer and use it in GitHub Desktop.
Measure throughput of memory
//! g++ -o copy_multi_area copy_multi_area.cpp -W -Wall -std=c++11 -O3 -mavx -funroll-loops
/*
* copy_multi_area.cpp
*
* Author: Makoto Shimazu <makoto.shimaz@gmail.com>
* URL: https://amiq11.tumblr.com
* License: MIT License
* Created: 2015-02-17
*
*/
#include <immintrin.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <iostream>
using namespace std;
#ifndef NUM_OF_PAGE
# define NUM_OF_PAGE 1
#endif
#ifndef nullptr
# define nullptr (0)
#endif
static const int32_t MB = 1024*1024;
// static const int32_t num_of_page = NUM_OF_PAGE;
static const int32_t num_of_page = 1;
static const int32_t default_repeats = 3;
static const int64_t default_size_mb = 1 * 1024;
double current_sec() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return (double)tv.tv_sec + (double)tv.tv_usec / 1E6;
}
// argv[1]: Total data size in MB
// argv[2]: Num of trials
int main(int argc, char *argv[])
{
int64_t size_mb = default_size_mb;
int32_t repeats = default_repeats;
if (argc >= 2)
size_mb = atoi(argv[1]);
if (argc >= 3)
repeats = atoi(argv[2]);
int64_t size_mb_per_page = size_mb / num_of_page;
uint8_t *src[num_of_page];
uint8_t *dst[num_of_page];
for (int i = 0; i < num_of_page; i++) {
src[i] = static_cast<uint8_t *>(_mm_malloc(size_mb_per_page * MB, 16));
dst[i] = static_cast<uint8_t *>(_mm_malloc(size_mb_per_page * MB, 16));
}
double dt[repeats];
double dt_sum = 0;
for (int r = 0; r < repeats; r++) {
// Initialize
for (int i = 0; i < num_of_page; i++) {
const int64_t block_size = sizeof(uint8_t) * MB;
// #pragma omp parallel for
// for (int n = 0; n < size_mb_per_page; n++) {
// uint8_t *src_begin = src[i] + block_size * n;
// uint8_t *dst_begin = dst[i] + block_size * n;
// memset(src_begin, 0, block_size * size_mb_per_page);
// memset(dst_begin, 0, block_size * size_mb_per_page);
// }
memset(src[i], 0, block_size * size_mb_per_page);
memset(dst[i], 0, block_size * size_mb_per_page);
}
// Workload
double t0 = current_sec();
asm volatile ("# ---- begin ----");
for (int64_t pos = 0; pos < size_mb_per_page * MB; pos++) {
// for loop version
// for (int i = 0; i < num_of_page; i++)
// dst[i][pos] = src[i][pos];
// unrolled version
dst[0][pos] = src[0][pos];
// dst[1][pos] = src[1][pos];
// dst[2][pos] = src[2][pos];
// dst[3][pos] = src[3][pos];
}
asm volatile ("# ---- end----");
double t1 = current_sec();
dt[r] = t1 - t0;
dt_sum += t1 - t0;
}
for (int i = 0; i < num_of_page; i++) {
_mm_free(src[i]);
_mm_free(dst[i]);
}
double dt_average = dt_sum / repeats;
double size_per_page = size_mb_per_page * MB;
double size_total = size_per_page * num_of_page;
double throughput_per_page = size_per_page / dt_average;
double throughput_total = size_total / dt_average;
// Tab separation to paste spreadsheet easily
cout << "Num: " << num_of_page << " "
<< "Time[s]: " << dt_average << " "
<< "Size[MB]: " << size_total / MB << " "
<< "Throughput[MB/s] " << throughput_total / MB << " "
<< "Throughput/Page[MB/s] " << throughput_per_page / MB << " "
<< "Each Throughput[MB/s]: "; // This enables you to calculate the confidence range
for (int r = 0; r < repeats; r++)
cout << size_total / dt[r] / MB << " ";
cout << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment