Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * io/flushbuffers.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008, 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 00012 **************************************************************************/ 00013 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::timestamp; 00025 using stxxl::file; 00026 using stxxl::request_ptr; 00027 00028 00029 #ifdef BLOCK_ALIGN 00030 #undef BLOCK_ALIGN 00031 #endif 00032 00033 #define BLOCK_ALIGN 4096 00034 00035 #define NOREAD 00036 00037 //#define DO_ONLY_READ 00038 00039 #define POLL_DELAY 1000 00040 00041 #define RAW_ACCESS 00042 00043 //#define WATCH_TIMES 00044 00045 00046 #ifdef WATCH_TIMES 00047 void watch_times(request_ptr reqs[], unsigned n, double * out) 00048 { 00049 bool * finished = new bool[n]; 00050 unsigned count = 0; 00051 unsigned i = 0; 00052 for (i = 0; i < n; i++) 00053 finished[i] = false; 00054 00055 00056 while (count != n) 00057 { 00058 usleep(POLL_DELAY); 00059 i = 0; 00060 for (i = 0; i < n; i++) 00061 { 00062 if (!finished[i]) 00063 if (reqs[i]->poll()) 00064 { 00065 finished[i] = true; 00066 out[i] = timestamp(); 00067 count++; 00068 } 00069 } 00070 } 00071 delete[] finished; 00072 } 00073 00074 00075 void out_stat(double start, double end, double * times, unsigned n, const std::vector<std::string> & names) 00076 { 00077 for (unsigned i = 0; i < n; i++) 00078 { 00079 std::cout << i << " " << names[i] << " took " << 00080 100. * (times[i] - start) / (end - start) << " %" << std::endl; 00081 } 00082 } 00083 #endif 00084 00085 #define MB (1024 * 1024) 00086 #define GB (1024 * 1024 * 1024) 00087 00088 int main(int argc, char * argv[]) 00089 { 00090 if (argc < 2) { 00091 std::cout << "Usage: " << argv[0] << " length_in_GiB diskfile..." << std::endl; 00092 return -1; 00093 } 00094 00095 stxxl::int64 offset = 0; 00096 stxxl::int64 end_offset = stxxl::int64(GB) * stxxl::int64(atoi(argv[1])); 00097 std::vector<std::string> disks_arr; 00098 00099 for (int ii = 2; ii < argc; ++ii) 00100 { 00101 std::cout << "# Add disk: " << argv[ii] << std::endl; 00102 disks_arr.push_back(argv[ii]); 00103 } 00104 00105 const unsigned ndisks = disks_arr.size(); 00106 const unsigned buffer_size = 1024 * 1024 * 64; 00107 const unsigned buffer_size_int = buffer_size / sizeof(int); 00108 const unsigned chunks = 32; 00109 request_ptr * reqs = new request_ptr[ndisks * chunks]; 00110 file ** disks = new file *[ndisks]; 00111 int * buffer = (int *)stxxl::aligned_alloc<BLOCK_ALIGN>(buffer_size * ndisks); 00112 #ifdef WATCH_TIMES 00113 double * r_finish_times = new double[ndisks]; 00114 double * w_finish_times = new double[ndisks]; 00115 #endif 00116 00117 int count = (end_offset - offset) / buffer_size; 00118 00119 unsigned i = 0, j = 0; 00120 00121 for (i = 0; i < ndisks * buffer_size_int; i++) 00122 buffer[i] = i; 00123 00124 for (i = 0; i < ndisks; i++) 00125 { 00126 disks[i] = new stxxl::syscall_file(disks_arr[i], 00127 file::CREAT | file::RDWR | file::DIRECT, i); 00128 } 00129 00130 while (count--) 00131 { 00132 std::cout << "Disk offset " << offset / MB << " MiB "; 00133 00134 double begin, end; 00135 00136 begin = timestamp(); 00137 00138 for (i = 0; i < ndisks; i++) 00139 { 00140 for (j = 0; j < chunks; j++) 00141 reqs[i * chunks + j] = 00142 disks[i]->aread(buffer + buffer_size_int * i + buffer_size_int * j / chunks, 00143 offset + buffer_size * j / chunks, 00144 buffer_size / chunks, 00145 stxxl::default_completion_handler()); 00146 } 00147 00148 #ifdef WATCH_TIMES 00149 watch_times(reqs, ndisks, r_finish_times); 00150 #else 00151 wait_all(reqs, ndisks * chunks); 00152 #endif 00153 00154 end = timestamp(); 00155 00156 std::cout << int(double(buffer_size) / MB / (end - begin)) << " MiB/s" << std::endl; 00157 00158 #ifdef WATCH_TIMES 00159 out_stat(begin, end, r_finish_times, ndisks, disks_arr); 00160 #endif 00161 00162 offset += /* 4*stxxl::int64(GB); */ buffer_size; 00163 } 00164 00165 for (i = 0; i < ndisks; i++) 00166 delete disks[i]; 00167 00168 delete[] reqs; 00169 delete[] disks; 00170 stxxl::aligned_dealloc<BLOCK_ALIGN>(buffer); 00171 00172 #ifdef WATCH_TIMES 00173 delete[] r_finish_times; 00174 delete[] w_finish_times; 00175 #endif 00176 00177 return 0; 00178 }