Вот такой код оно дало:
#include <iostream>
#include <chrono>
#include <cstdint>
#include <cstdlib> // std::strtod
#include <new> // std::bad_alloc
#include <algorithm> // std::max
static double toGiB(std::uint64_t bytes)
{
constexpr double GiB = 1024.0 * 1024.0 * 1024.0;
return static_cast<double>(bytes) / GiB;
}
int main(int argc, char** argv)
{
// Размер по умолчанию: 1 GiB
double requestedGiB = 1.0;
if (argc >= 2) {
requestedGiB = std::strtod(argv[1], nullptr);
if (!(requestedGiB > 0.0)) {
std::cerr << "Usage: " << argv[0] << " [size_in_GiB]\n";
return 1;
}
}
constexpr std::uint64_t GiB = 1024ull * 1024 * 1024;
std::uint64_t bytesRequested = static_cast<std::uint64_t>(requestedGiB * static_cast<double>(GiB));
// Выравниваем вниз до размера элемента, чтобы не выйти за границы.
std::uint64_t elementCount = bytesRequested / sizeof(std::uint64_t);
std::uint64_t bytes = elementCount * sizeof(std::uint64_t);
if (elementCount == 0) {
std::cerr << "Requested size is too small.\n";
return 1;
}
std::cout << "Requested: " << requestedGiB << " GiB\n";
std::cout << "Actual: " << toGiB(bytes) << " GiB (" << bytes << " bytes)\n";
std::cout << "Elements: " << elementCount << " x uint64_t\n\n";
using clock = std::chrono::steady_clock;
// --------------------
// Allocation test
// --------------------
std::cout << "Allocating...\n";
std::uint64_t* buffer = nullptr;
auto allocStart = clock::now();
try {
// Не инициализирует память, только выделяет
buffer = static_cast<std::uint64_t*>(::operator new[](bytes));
} catch (const std::bad_alloc&) {
std::cerr << "Allocation failed (bad_alloc).\n";
return 1;
}
auto allocEnd = clock::now();
std::chrono::duration<double> allocDuration = allocEnd - allocStart;
double allocGiBs = toGiB(bytes) / std::max(allocDuration.count(), 1e-12);
// --------------------
// Write test (first touch)
// --------------------
auto writeStart = clock::now();
for (std::uint64_t i = 0; i < elementCount; ++i)
buffer[i] = i;
auto writeEnd = clock::now();
std::chrono::duration<double> writeDuration = writeEnd - writeStart;
double writeGiBs = toGiB(bytes) / std::max(writeDuration.count(), 1e-12);
// --------------------
// Read test
// --------------------
volatile std::uint64_t sink = 0;
auto readStart = clock::now();
for (std::uint64_t i = 0; i < elementCount; ++i)
sink += buffer[i];
auto readEnd = clock::now();
std::chrono::duration<double> readDuration = readEnd - readStart;
double readGiBs = toGiB(bytes) / std::max(readDuration.count(), 1e-12);
// --------------------
// Cleanup
// --------------------
::operator delete[](buffer);
// --------------------
// Results
// --------------------
std::cout << "\nResults:\n";
std::cout << "Alloc time : " << allocDuration.count() << " s (" << allocGiBs << " GiB/s)\n";
std::cout << "Write time : " << writeDuration.count() << " s (" << writeGiBs << " GiB/s)\n";
std::cout << "Read time : " << readDuration.count() << " s (" << readGiBs << " GiB/s)\n";
std::cout << "Checksum : " << sink << "\n";
return 0;
}
Какие-то проги находил, но все какие-то стремные. Что лучше юзать?