1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include "ns3/core-module.h"
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace ns3;
/**
* @ingroup system-tests-perf
*
* Check the performance of writing to file.
*
* @param file The file to write to.
* @param n The number of writes to perform.
* @param buffer The buffer to write.
* @param size The buffer size.
*/
void
PerfFile(FILE* file, uint32_t n, const char* buffer, uint32_t size)
{
for (uint32_t i = 0; i < n; ++i)
{
if (std::fwrite(buffer, 1, size, file) != size)
{
NS_ABORT_MSG("PerfFile(): fwrite error");
}
}
}
/**
* @ingroup system-tests-perf
*
* Check the performance of writing to an output stream.
*
* @param stream The output stream to write to.
* @param n The number of writes to perform.
* @param buffer The buffer to write.
* @param size The buffer size.
*/
void
PerfStream(std::ostream& stream, uint32_t n, const char* buffer, uint32_t size)
{
for (uint32_t i = 0; i < n; ++i)
{
stream.write(buffer, size);
}
}
int
main(int argc, char* argv[])
{
uint32_t n = 100000;
uint32_t iter = 50;
bool doStream = false;
bool binmode = true;
CommandLine cmd(__FILE__);
cmd.AddValue("n", "How many times to write (defaults to 100000", n);
cmd.AddValue("iter", "How many times to run the test looking for a min (defaults to 50)", iter);
cmd.AddValue("doStream", "Run the C++ I/O benchmark otherwise the C I/O ", doStream);
cmd.AddValue("binmode",
"Select binary mode for the C++ I/O benchmark (defaults to true)",
binmode);
cmd.Parse(argc, argv);
auto minResultNs =
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::nanoseconds::max());
char buffer[1024];
if (doStream)
{
//
// This will probably run on a machine doing other things. Run it some
// relatively large number of times and try to find a minimum, which
// will hopefully represent a time when it runs free of interference.
//
for (uint32_t i = 0; i < iter; ++i)
{
std::ofstream stream;
if (binmode)
{
stream.open("streamtest", std::ios_base::binary | std::ios_base::out);
}
else
{
stream.open("streamtest", std::ios_base::out);
}
auto start = std::chrono::steady_clock::now();
PerfStream(stream, n, buffer, 1024);
auto end = std::chrono::steady_clock::now();
auto resultNs = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
resultNs = std::min(resultNs, minResultNs);
stream.close();
std::cout << ".";
std::cout.flush();
}
std::cout << std::endl;
}
else
{
//
// This will probably run on a machine doing other things. Run it some
// relatively large number of times and try to find a minimum, which
// will hopefully represent a time when it runs free of interference.
//
for (uint32_t i = 0; i < iter; ++i)
{
FILE* file = fopen("filetest", "w");
auto start = std::chrono::steady_clock::now();
PerfFile(file, n, buffer, 1024);
auto end = std::chrono::steady_clock::now();
auto resultNs = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
resultNs = std::min(resultNs, minResultNs);
fclose(file);
file = nullptr;
std::cout << ".";
std::cout.flush();
}
std::cout << std::endl;
}
std::cout << argv[0] << ": " << minResultNs.count() << "ns" << std::endl;
return 0;
}
|