Revision f12339cf
Added by david.sorber about 3 years ago
| software/read_test/src/main.cc | ||
|---|---|---|
|
#include <algorithm>
|
||
|
#include <chrono>
|
||
|
#include <cstdlib>
|
||
|
#include <filesystem>
|
||
|
#include <iomanip>
|
||
|
#include <iostream>
|
||
|
#include <string>
|
||
| ... | ... | |
|
#include "URingExecDriver.h"
|
||
|
#include "Utilities/BufferAllocator.h"
|
||
|
#include "Utilities/FileUtils.h"
|
||
|
#include "Utilities/SearchLynxConfiguration.h"
|
||
|
|
||
|
// Alias the namespace for readability
|
||
|
namespace bpo = boost::program_options;
|
||
|
namespace bsl = BlackLynx::SearchLynx;
|
||
|
namespace sfs = std::filesystem;
|
||
|
|
||
|
const std::string BOLD("\033[1m");
|
||
|
const std::string ENDC("\033[0m");
|
||
| ... | ... | |
|
const std::string YELLOW("\033[33m");
|
||
|
const std::string UP_ONE = "\033[1A";
|
||
|
|
||
|
const std::string VERSION("ReadTest version 1.1.0-dev");
|
||
|
const std::string VERSION("ReadTest version 1.2.0-dev");
|
||
|
|
||
|
std::vector<std::string> UNITS{"b/sec", "KB/s", "MB/s", "GB/s", "TB/s"};
|
||
|
const std::vector<std::string> UNITS{"b/sec", "KB/s", "MB/s", "GB/s", "TB/s"};
|
||
|
|
||
|
double printRate(double rawRate, uint32_t& unitIdx)
|
||
|
{
|
||
| ... | ... | |
|
|
||
|
void usage()
|
||
|
{
|
||
|
std::cout << BOLD << "Read Test Utility\n\n" << ENDC;
|
||
|
std::cout << "Usage: read_test <--help | -h>\n";
|
||
|
std::cout << " read_test --version\n";
|
||
|
std::cout << BOLD << "Read Test Utility\n\n" << ENDC
|
||
|
<< "Usage: read_test <--help | -h>\n"
|
||
|
<< " read_test --version\n\n"
|
||
|
<< "Options:\n"
|
||
|
<< " --input-file Path to the file to read.\n"
|
||
|
<< " --read-type The type of read to perform: auto, normal, aio, or uring\n"
|
||
|
<< " --num-threads The number of reader threads to use.\n"
|
||
|
<< " --chunk-size Chunk size in kilobytes.\n\n";
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
| ... | ... | |
|
// Extract the first string from 'values'. If there is more than one string,
|
||
|
// it's an error, and exception will be thrown.
|
||
|
std::string val = bpo::validators::get_single_string(values);
|
||
|
// BlackLynx::SearchLynx::CharacterUtilities::lowercaseInPlace(val);
|
||
|
lowercase(val);
|
||
|
// Check for valid values
|
||
|
if (val == "auto" || val == "normal" || val == "aio" || val == "uring")
|
||
| ... | ... | |
|
{
|
||
|
bpo::variables_map optionsMap;
|
||
|
ReadTypeValue readType("default");
|
||
|
std::string filename;
|
||
|
std::string filePath;
|
||
|
uint32_t numThreads = 0;
|
||
|
uint32_t chunkSize = 65536; // in Kb
|
||
|
|
||
|
try
|
||
|
{
|
||
| ... | ... | |
|
("num-threads", bpo::value<uint32_t>(&numThreads),
|
||
|
"number reader threads")
|
||
|
|
||
|
("input-file", bpo::value<std::string>(&filename)->required(),
|
||
|
("input-file", bpo::value<std::string>(&filePath)->required(),
|
||
|
"input file")
|
||
|
|
||
|
("chunk-size", bpo::value<uint32_t>(&chunkSize), "chunk size in Kb")
|
||
|
;
|
||
|
|
||
|
// Positional options
|
||
| ... | ... | |
|
|
||
|
std::cout << "Read Test Utility\n" << std::endl;
|
||
|
std::cout << "Read type: " << readType.value << "\n";
|
||
|
std::cout << "Input file: " << filename << "\n";
|
||
|
std::cout << "Input file: " << filePath << "\n";
|
||
|
|
||
|
// Valid kernel version if user selected uring read type
|
||
|
// Validate kernel version if user selected uring read type
|
||
|
if (readType.getValue() == ReadType::URING &&
|
||
|
(! validateKernelVersion(5, 6, 0)))
|
||
|
{
|
||
| ... | ... | |
|
// Start time measurement
|
||
|
auto start = std::chrono::system_clock::now();
|
||
|
|
||
|
uint64_t fileSize = sfs::file_size(filePath);
|
||
|
|
||
|
// Prime the config object then allocate buffers
|
||
|
auto slConfig = bsl::SearchLynxConfiguration::getInstance();
|
||
|
auto bufAllocator = bsl::BufferAllocator::getInstance();
|
||
|
bufAllocator->initAllocation();
|
||
|
bufAllocator->initAllocation(chunkSize, fileSize);
|
||
|
|
||
|
// Use the read type argument to decide which ExecDriver instance to create
|
||
|
bsl::ExecDriver* driver = nullptr;
|
||
| ... | ... | |
|
{
|
||
|
numThreads = 3;
|
||
|
}
|
||
|
driver = new bsl::AIO_ExecDriver(filename, numThreads);
|
||
|
driver = new bsl::AIO_ExecDriver(filePath, numThreads, chunkSize);
|
||
|
break;
|
||
|
|
||
|
case ReadType::NORMAL:
|
||
| ... | ... | |
|
{
|
||
|
numThreads = 22;
|
||
|
}
|
||
|
driver = new bsl::ExecDriver(filename, numThreads);
|
||
|
driver = new bsl::ExecDriver(filePath, numThreads, chunkSize);
|
||
|
break;
|
||
|
|
||
|
case ReadType::URING:
|
||
|
numThreads = 1;
|
||
|
driver = new bsl::URingExecDriver(filename, 1);
|
||
|
driver = new bsl::URingExecDriver(filePath, 1, chunkSize);
|
||
|
break;
|
||
|
}
|
||
|
std::cout << "Num threads: " << numThreads << "\n";
|
||
|
std::cout << "Chunk size: " << chunkSize << "\n";
|
||
|
|
||
|
driver->start();
|
||
|
driver->waitUntilComplete();
|
||
| ... | ... | |
|
std::cout << "Duration: " << std::fixed << std::setprecision(3)
|
||
|
<< duration << " ms" << std::endl;
|
||
|
|
||
|
uint64_t fileSize = bsl::FileUtils::getFileSize(filename);
|
||
|
|
||
|
double rawRate = fileSize / duration;
|
||
|
std::cout << "Raw rate: " << rawRate << " b/sec" << std::endl;
|
||
|
|
||
Clean up read test code. Add liburing 2.4 as external source.