2022-06-22 15:40:48 +00:00
|
|
|
#include "gen.hh"
|
2022-05-25 10:55:01 +00:00
|
|
|
#include <cstdlib>
|
2022-11-01 10:01:23 +00:00
|
|
|
#include <cstring>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
2022-02-21 13:41:40 +00:00
|
|
|
#include "ntr.h"
|
2022-11-01 10:01:23 +00:00
|
|
|
#include "nms.h"
|
2022-02-21 13:41:40 +00:00
|
|
|
#include <getopt.h>
|
|
|
|
#include <unistd.h>
|
2022-06-22 15:40:48 +00:00
|
|
|
#include <topo.h>
|
2022-02-21 13:41:40 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
usage()
|
|
|
|
{
|
|
|
|
fprintf(stdout,
|
|
|
|
"Usage:\n"
|
|
|
|
" -v: verbose mode\n"
|
2022-11-01 10:01:23 +00:00
|
|
|
" -b: memory block size\n"
|
|
|
|
" -d: destination domain index\n"
|
|
|
|
" -s: worker threads cpu list\n"
|
|
|
|
" -S: enable shared memory block\n"
|
|
|
|
" -t: time to run\n"
|
|
|
|
" -o: output file path\n");
|
2022-02-21 13:41:40 +00:00
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
2022-11-01 10:01:23 +00:00
|
|
|
static char output_file[256] = "memloadgen_samples.txt";
|
|
|
|
|
2022-02-21 13:41:40 +00:00
|
|
|
int main(int argc, char * argv[])
|
|
|
|
{
|
|
|
|
ntr_init();
|
|
|
|
ntr_set_level(NTR_DEP_USER1, NTR_LEVEL_WARNING);
|
|
|
|
|
2022-11-01 10:01:23 +00:00
|
|
|
size_t arr_sz = 1024 * 1024;
|
|
|
|
uint32_t time = -1;
|
2022-06-22 15:40:48 +00:00
|
|
|
cpuset_t threads;
|
2022-11-01 10:01:23 +00:00
|
|
|
CPU_ZERO(&threads);
|
|
|
|
CPU_SET(0, &threads);
|
|
|
|
|
2022-06-22 15:40:48 +00:00
|
|
|
int shared_buffer = 0;
|
|
|
|
cpuset_t domain_mask;
|
2022-11-01 10:01:23 +00:00
|
|
|
CPU_ZERO(&domain_mask);
|
|
|
|
CPU_SET(0, &domain_mask);
|
2022-02-21 13:41:40 +00:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
// parse arguments
|
2022-11-01 10:01:23 +00:00
|
|
|
while ((c = getopt(argc, argv, "vhb:d:s:So:t:")) != -1) {
|
2022-02-21 13:41:40 +00:00
|
|
|
switch (c) {
|
|
|
|
case 'v':
|
2022-11-01 10:01:23 +00:00
|
|
|
ntr_set_level(NTR_DEP_USER1, ntr_get_level(NTR_DEP_USER1) + 1);
|
2022-02-21 13:41:40 +00:00
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
usage();
|
|
|
|
exit(0);
|
|
|
|
case 'b':
|
2022-06-22 15:40:48 +00:00
|
|
|
arr_sz = strtoull(optarg, nullptr, 10);
|
2022-05-25 10:55:01 +00:00
|
|
|
break;
|
2022-11-01 10:01:23 +00:00
|
|
|
case 'd':
|
2022-06-22 15:40:48 +00:00
|
|
|
cpulist_to_cpuset(optarg, &domain_mask);
|
2022-02-21 13:41:40 +00:00
|
|
|
break;
|
2022-11-01 10:01:23 +00:00
|
|
|
case 's':
|
2022-06-22 15:40:48 +00:00
|
|
|
cpulist_to_cpuset(optarg, &threads);
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
shared_buffer = 1;
|
2022-02-21 13:41:40 +00:00
|
|
|
break;
|
2022-11-01 10:01:23 +00:00
|
|
|
case 'o':
|
|
|
|
strncpy(output_file, optarg, 256);
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
time = (uint32_t)strtol(optarg, nullptr, 10);
|
2022-11-01 10:27:34 +00:00
|
|
|
break;
|
2022-02-21 13:41:40 +00:00
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-01 10:01:23 +00:00
|
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "MLG: [size: %ld, # threads: 0x%d, domain: 0x%ld]\n", arr_sz, CPU_COUNT(&threads), CPU_FFS(&domain_mask) - 1);
|
2022-02-21 13:41:40 +00:00
|
|
|
|
2022-06-22 15:40:48 +00:00
|
|
|
// init topo
|
2022-11-01 10:01:23 +00:00
|
|
|
if (topo_init(ntr_get_level(NTR_DEP_USER1) != NTR_LEVEL_DEFAULT)) {
|
2022-06-22 15:40:48 +00:00
|
|
|
fprintf(stderr, "libtopo init failed!\n");
|
2022-02-21 13:41:40 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2022-11-01 10:01:23 +00:00
|
|
|
// init
|
|
|
|
if (nms_init(ntr_get_level(NTR_DEP_USER1) != NTR_LEVEL_DEFAULT)) {
|
|
|
|
fprintf(stderr, "libnms init failed!\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2022-02-21 13:41:40 +00:00
|
|
|
bool success = false;
|
2022-06-22 15:40:48 +00:00
|
|
|
memload_generator::memload_generator_options opts;
|
|
|
|
opts.chunk_size = arr_sz;
|
|
|
|
opts.shared_buffer = shared_buffer;
|
2022-11-01 10:01:23 +00:00
|
|
|
opts.verbose = ntr_get_level(NTR_DEP_USER1) != NTR_LEVEL_DEFAULT;
|
|
|
|
|
|
|
|
std::ofstream ofile;
|
|
|
|
ofile.open(output_file, std::ios::out | std::ios::trunc);
|
2022-02-21 13:41:40 +00:00
|
|
|
|
2022-06-22 15:40:48 +00:00
|
|
|
auto mgen = new memload_generator(&threads, &domain_mask, &opts, &success);
|
2022-11-01 10:01:23 +00:00
|
|
|
if (!mgen->start()) {
|
|
|
|
fprintf(stderr, "failed to start memloadgen!\n");
|
|
|
|
exit(1);
|
2022-02-21 13:41:40 +00:00
|
|
|
}
|
|
|
|
|
2022-11-01 10:01:23 +00:00
|
|
|
uint64_t prev_ts = topo_uptime_ns();
|
|
|
|
uint64_t prev_trans = mgen->get_transactions();
|
|
|
|
uint32_t cur_time = 0;
|
|
|
|
while(cur_time < time) {
|
|
|
|
usleep(S2US);
|
|
|
|
uint64_t cur_ts = topo_uptime_ns();
|
|
|
|
uint64_t trans = mgen->get_transactions();
|
|
|
|
uint64_t bps = (uint64_t)((double)((trans - prev_trans) * arr_sz) / ((double)(cur_ts - prev_ts) / (double)S2NS));
|
|
|
|
|
|
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "main: MLG bps = %ld ~= %ldM\n", bps, bps / 1024 / 1024);
|
|
|
|
ofile << bps << std::endl;
|
2022-05-25 10:55:01 +00:00
|
|
|
|
2022-11-01 10:01:23 +00:00
|
|
|
prev_ts = cur_ts;
|
|
|
|
prev_trans = trans;
|
|
|
|
cur_time++;
|
|
|
|
}
|
|
|
|
mgen->stop();
|
2022-06-22 15:40:48 +00:00
|
|
|
delete mgen;
|
2022-11-01 10:01:23 +00:00
|
|
|
ofile.close();
|
2022-06-22 15:40:48 +00:00
|
|
|
|
2022-02-21 13:41:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|