Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * io/benchmark_disk_and_flash.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de.de> 00007 * 00008 * Distributed under the Boost Software License, Version 1.0. 00009 * (See accompanying file LICENSE_1_0.txt or copy at 00010 * http://www.boost.org/LICENSE_1_0.txt) 00011 **************************************************************************/ 00012 00013 #include <iomanip> 00014 #include <vector> 00015 00016 #include <stxxl/io> 00017 #include <stxxl/aligned_alloc> 00018 00019 #ifndef BOOST_MSVC 00020 #include <unistd.h> 00021 #endif 00022 00023 00024 using stxxl::request_ptr; 00025 using stxxl::file; 00026 using stxxl::timestamp; 00027 00028 00029 #ifdef BLOCK_ALIGN 00030 #undef BLOCK_ALIGN 00031 #endif 00032 00033 #define BLOCK_ALIGN 4096 00034 00035 #define KB (1024) 00036 #define MB (1024 * 1024) 00037 #define GB (1024 * 1024 * 1024) 00038 00039 void run(char * buffer, file ** disks, stxxl::int64 offset, stxxl::int64 length, 00040 unsigned hdd_blocks, unsigned hdd_bytes, unsigned ssd_blocks, unsigned ssd_bytes, unsigned repeats) 00041 { 00042 unsigned i, j; 00043 double begin = timestamp(), end, elapsed; 00044 request_ptr * reqs = new request_ptr[stxxl::STXXL_MAX(hdd_blocks + ssd_blocks, 1U)]; 00045 00046 struct diskinfo { 00047 unsigned id; 00048 unsigned bytes; 00049 unsigned n; 00050 }; 00051 00052 diskinfo info[2]; 00053 00054 // HDD 00055 info[0].id = 0; 00056 info[0].bytes = hdd_bytes; 00057 info[0].n = hdd_blocks; 00058 00059 // SSD 00060 info[1].id = 1; 00061 info[1].bytes = ssd_bytes; 00062 info[1].n = ssd_blocks; 00063 00064 begin = timestamp(); 00065 double volume = 0; 00066 00067 for (unsigned repeat = 0; repeat < repeats; ++repeat) { 00068 int r = 0; 00069 char * buf = buffer; 00070 for (i = 0; i < 2; i++) 00071 { 00072 for (j = 0; j < info[i].n; j++) { 00073 stxxl::int64 bytes = info[i].bytes; 00074 stxxl::int64 position = (bytes * (rand() & 0xffff)) % length; 00075 reqs[r++] = disks[info[i].id]->aread(buf, offset + position, bytes, 00076 stxxl::default_completion_handler()); 00077 buf += bytes; 00078 volume += bytes; 00079 } 00080 } 00081 00082 wait_all(reqs, r); 00083 } 00084 00085 end = timestamp(); 00086 elapsed = end - begin; 00087 00088 std::cout << "B_d = " << info[0].bytes << " B_f = " << info[1].bytes << " n_d = " << info[0].n << " n_f = " << info[1].n; //<< std::endl; 00089 std::cout << " Transferred " << (volume / MB) << " MiB in " << elapsed << " seconds @ " << (volume / MB / elapsed) << " MiB/s" << std::endl; 00090 delete[] reqs; 00091 } 00092 00093 void usage(const char * argv0) 00094 { 00095 std::cout << "Usage: " << argv0 << " offset length diskfile flashfile" << std::endl; 00096 std::cout << " starting 'offset' and 'length' are given in GiB" << std::endl; 00097 std::cout << " length == 0 implies till end of space (please ignore the write error)" << std::endl; 00098 exit(-1); 00099 } 00100 00101 int main(int argc, char * argv[]) 00102 { 00103 if (argc < 4) 00104 usage(argv[0]); 00105 00106 stxxl::int64 offset = stxxl::int64(GB) * stxxl::int64(atoi(argv[1])); 00107 stxxl::int64 length = stxxl::int64(GB) * stxxl::int64(atoi(argv[2])); 00108 00109 int first_disk_arg = 3; 00110 00111 std::vector<std::string> disks_arr; 00112 00113 if (!(first_disk_arg < argc)) 00114 usage(argv[0]); 00115 00116 for (int ii = first_disk_arg; ii < argc; ii++) 00117 { 00118 std::cout << "# Add disk: " << argv[ii] << std::endl; 00119 disks_arr.push_back(argv[ii]); 00120 } 00121 00122 const unsigned ndisks = disks_arr.size(); 00123 stxxl::int64 buffer_size = 1024 * MB; 00124 const stxxl::int64 buffer_size_int = buffer_size / sizeof(int); 00125 00126 unsigned i; 00127 00128 file ** disks = new file *[ndisks]; 00129 unsigned * buffer = (unsigned *)stxxl::aligned_alloc<BLOCK_ALIGN>(buffer_size); 00130 00131 for (i = 0; i < buffer_size_int; i++) 00132 buffer[i] = i; 00133 00134 for (i = 0; i < ndisks; i++) 00135 { 00136 disks[i] = new stxxl::syscall_file(disks_arr[i], 00137 file::CREAT | file::RDWR | file::DIRECT, i); 00138 } 00139 00140 try { 00141 run((char *)buffer, disks, offset, length, 1, 2 * MB, 23, 128 * 1024, 100); 00142 run((char *)buffer, disks, offset, length, 1, 2 * MB, 42, 128 * 1024, 100); 00143 for (unsigned hdd_bytes = 4 * KB; hdd_bytes < 256 * MB; hdd_bytes <<= 1) { 00144 for (unsigned ssd_bytes = 128 * KB; ssd_bytes == 128 * KB; ssd_bytes <<= 1) { 00145 for (unsigned hdd_blocks = 1; hdd_blocks == 1; ++hdd_blocks) { 00146 for (unsigned ssd_blocks = 0; ssd_blocks <= (stxxl::STXXL_MAX(16U, 2 * hdd_bytes * hdd_blocks / ssd_bytes)); ++ssd_blocks) { 00147 run((char *)buffer, disks, offset, length, hdd_blocks, hdd_bytes, ssd_blocks, ssd_bytes, 100); 00148 } 00149 } 00150 } 00151 } 00152 } 00153 catch (const std::exception & ex) 00154 { 00155 std::cout << std::endl; 00156 STXXL_ERRMSG(ex.what()); 00157 } 00158 00159 for (i = 0; i < ndisks; i++) 00160 delete disks[i]; 00161 00162 delete[] disks; 00163 stxxl::aligned_dealloc<BLOCK_ALIGN>(buffer); 00164 00165 return 0; 00166 } 00167 00168 // vim: et:ts=4:sw=4