http://stxxl.sourceforge.net
<beckmann@cs.uni-frankfurt.de>
http://www.boost.org/LICENSE_1_0.txt
#include <iomanip>
#include <vector>
#include <stxxl/io>
#include <stxxl/aligned_alloc>
using stxxl::request_ptr;
using stxxl::file;
using stxxl::timestamp;
#ifdef BLOCK_ALIGN
#undef BLOCK_ALIGN
#endif
#define BLOCK_ALIGN 4096
#define KB (1024)
#define MB (1024 * 1024)
#define GB (1024 * 1024 * 1024)
void run(char* buffer, file** disks, stxxl::int64 offset, stxxl::int64 length,
unsigned hdd_blocks, unsigned hdd_bytes, unsigned ssd_blocks, unsigned ssd_bytes, unsigned repeats)
{
unsigned i, j;
double begin = timestamp(), end, elapsed;
request_ptr* reqs = new request_ptr[stxxl::STXXL_MAX(hdd_blocks + ssd_blocks, 1U)];
struct diskinfo {
unsigned id;
unsigned bytes;
unsigned n;
};
diskinfo info[2];
info[0].id = 0;
info[0].bytes = hdd_bytes;
info[0].n = hdd_blocks;
info[1].id = 1;
info[1].bytes = ssd_bytes;
info[1].n = ssd_blocks;
begin = timestamp();
double volume = 0;
for (unsigned repeat = 0; repeat < repeats; ++repeat) {
int r = 0;
char* buf = buffer;
for (i = 0; i < 2; i++)
{
for (j = 0; j < info[i].n; j++) {
stxxl::int64 bytes = info[i].bytes;
stxxl::int64 position = (bytes * (rand() & 0xffff)) % length;
reqs[r++] = disks[info[i].id]->aread(buf, offset + position, bytes,
stxxl::default_completion_handler());
buf += bytes;
volume += bytes;
}
}
wait_all(reqs, r);
}
end = timestamp();
elapsed = end - begin;
std::cout << "B_d = " << info[0].bytes << " B_f = " << info[1].bytes << " n_d = " << info[0].n << " n_f = " << info[1].n;
std::cout << " Transferred " << (volume / MB) << " MiB in " << elapsed << " seconds @ " << (volume / MB / elapsed) << " MiB/s" << std::endl;
delete[] reqs;
}
void usage(const char* argv0)
{
std::cout << "Usage: " << argv0 << " offset length diskfile flashfile" << std::endl;
std::cout << " starting 'offset' and 'length' are given in GiB" << std::endl;
std::cout << " length == 0 implies till end of space (please ignore the write error)" << std::endl;
exit(-1);
}
int main(int argc, char* argv[])
{
if (argc < 4)
usage(argv[0]);
stxxl::int64 offset = stxxl::int64(GB) * stxxl::int64(atoi(argv[1]));
stxxl::int64 length = stxxl::int64(GB) * stxxl::int64(atoi(argv[2]));
int first_disk_arg = 3;
std::vector<std::string> disks_arr;
if (!(first_disk_arg < argc))
usage(argv[0]);
for (int ii = first_disk_arg; ii < argc; ii++)
{
std::cout << "# Add disk: " << argv[ii] << std::endl;
disks_arr.push_back(argv[ii]);
}
const size_t ndisks = disks_arr.size();
stxxl::int64 buffer_size = 1024 * MB;
const stxxl::int64 buffer_size_int = buffer_size / sizeof(int);
unsigned i;
file** disks = new file*[ndisks];
unsigned* buffer = (unsigned*)stxxl::aligned_alloc<BLOCK_ALIGN>(buffer_size);
for (i = 0; i < buffer_size_int; i++)
buffer[i] = i;
for (i = 0; i < ndisks; i++)
{
disks[i] = new stxxl::syscall_file(disks_arr[i],
file::CREAT | file::RDWR | file::DIRECT, i);
}
try {
run((char*)buffer, disks, offset, length, 1, 2 * MB, 23, 128 * 1024, 100);
run((char*)buffer, disks, offset, length, 1, 2 * MB, 42, 128 * 1024, 100);
for (unsigned hdd_bytes = 4 * KB; hdd_bytes < 256 * MB; hdd_bytes <<= 1) {
for (unsigned ssd_bytes = 128 * KB; ssd_bytes == 128 * KB; ssd_bytes <<= 1) {
for (unsigned hdd_blocks = 1; hdd_blocks == 1; ++hdd_blocks) {
for (unsigned ssd_blocks = 0; ssd_blocks <= (stxxl::STXXL_MAX(16U, 2 * hdd_bytes * hdd_blocks / ssd_bytes)); ++ssd_blocks) {
run((char*)buffer, disks, offset, length, hdd_blocks, hdd_bytes, ssd_blocks, ssd_bytes, 100);
}
}
}
}
}
catch (const std::exception& ex)
{
std::cout << std::endl;
STXXL_ERRMSG(ex.what());
}
for (i = 0; i < ndisks; i++)
delete disks[i];
delete[] disks;
stxxl::aligned_dealloc<BLOCK_ALIGN>(buffer);
return 0;
}