Skip to content

Instantly share code, notes, and snippets.

@Lazin
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lazin/0cb54feefa1c5c17ecf7 to your computer and use it in GitHub Desktop.
Save Lazin/0cb54feefa1c5c17ecf7 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cstdio>
#include <stdexcept>
#include <unistd.h>
#include <thread>
#include <vector>
#include <cstring>
#include <time.h>
class PerfTimer
{
public:
PerfTimer();
void restart();
double elapsed() const;
private:
timespec _start_time;
};
PerfTimer::PerfTimer() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_start_time);
}
void PerfTimer::restart() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_start_time);
}
double PerfTimer::elapsed() const {
timespec curr;
clock_gettime(CLOCK_MONOTONIC_RAW, &curr);
return double(curr.tv_sec - _start_time.tv_sec) +
double(curr.tv_nsec - _start_time.tv_nsec)/1000000000.0;
}
const char* PATH = "/tmp/perftest.tmp";
const size_t FSIZE = 10/*GB*/*1024*1024*1024l;
const int NREGIONS = 4;
FILE* create_file() {
auto res = fopen(PATH, "w");
if (res == nullptr) {
throw std::runtime_error("can't open file");
}
return res;
}
void truncate(FILE* file) {
int fd = fileno(file);
if (ftruncate(fd, FSIZE)) {
throw std::runtime_error("can't truncate file");
}
}
void close(FILE* file) {
if (fclose(file) != 0) {
throw std::runtime_error("can't close file");
}
}
int main() {
std::cout << "Creating " << PATH << " file" << std::endl;
try {
FILE* file = create_file();
truncate(file);
std::vector<std::thread> threads;
PerfTimer total;
for (int jobix = NREGIONS; jobix-->0;) {
threads.emplace_back([jobix]() {
try {
FILE* file = create_file();
PerfTimer jobtm;
int fd = fileno(file);
const size_t BUFSIZE = 0x1000;
std::vector<char> buffer;
buffer.resize(BUFSIZE);
for (int i = 0; i < BUFSIZE; i++) {
buffer[i] = 32 + rand()%10;
}
const size_t BLOCKSIZE = FSIZE/NREGIONS;
const size_t INITIAL_OFF = jobix*BUFSIZE;
const size_t LAST_OFF = FSIZE;
for (size_t offset = INITIAL_OFF; offset < LAST_OFF; offset += BUFSIZE*NREGIONS) {
fseek(file, offset, SEEK_SET);
if (write(fd, buffer.data(), BUFSIZE) < 0) {
throw std::runtime_error("can't write data to file");
}
}
fflush(file);
close(file);
std::cout << "job " << jobix << " done in " << jobtm.elapsed() << " seconds " << "\n";
} catch (const std::exception& e) {
std::cout << "error in job " << jobix << ": " << e.what() << std::endl;
}
});
}
for (int jobix = NREGIONS; jobix-->0;) {
threads.at(jobix).join();
}
close(file);
std::cout << "done in " << total.elapsed() << " seconds" << std::endl;
} catch (const std::exception& e) {
std::cout << "error main " << e.what() << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment