00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00019
00020
00021 #include <stxxl/stack>
00022
00023 #define MEM_2_RESERVE (768 * 1024 * 1024)
00024
00025 #ifndef BLOCK_SIZE
00026 #define BLOCK_SIZE (2 * 1024 * 1024)
00027 #endif
00028
00029 #ifndef DISKS
00030 #define DISKS 4
00031 #endif
00032
00033 template <unsigned RECORD_SIZE>
00034 struct my_record_
00035 {
00036 char data[RECORD_SIZE];
00037 my_record_()
00038 {
00039 memset(data, 0, sizeof(data));
00040 }
00041 };
00042
00043 template <unsigned RECORD_SIZE>
00044 inline std::ostream & operator << (std::ostream & o, const my_record_<RECORD_SIZE> &)
00045 {
00046 o << ".";
00047 return o;
00048 }
00049
00050 template <class my_record>
00051 void run_stxxl_growshrink2_stack(stxxl::int64 volume)
00052 {
00053 typedef typename stxxl::STACK_GENERATOR<my_record, stxxl::external,
00054 stxxl::grow_shrink2, DISKS, BLOCK_SIZE>::result stack_type;
00055 typedef typename stack_type::block_type block_type;
00056
00057 STXXL_MSG("Record size: " << sizeof(my_record) << " bytes");
00058
00059 stxxl::prefetch_pool<block_type> p_pool(DISKS * 4);
00060 stxxl::write_pool<block_type> w_pool(DISKS * 4);
00061
00062 stack_type Stack(p_pool, w_pool);
00063
00064 stxxl::int64 ops = volume / sizeof(my_record);
00065
00066 stxxl::int64 i;
00067
00068 my_record cur;
00069
00070 stxxl::stats * Stats = stxxl::stats::get_instance();
00071 Stats->reset();
00072
00073 stxxl::timer Timer;
00074 Timer.start();
00075
00076 for (i = 0; i < ops; ++i)
00077 {
00078 Stack.push(cur);
00079 }
00080
00081 Timer.stop();
00082
00083 STXXL_MSG("Records in Stack: " << Stack.size());
00084 if (i != Stack.size())
00085 {
00086 STXXL_MSG("Size does not match");
00087 abort();
00088 }
00089
00090 STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) <<
00091 " seconds : " << (double(volume) / (1024. * 1024. * Timer.mseconds() / 1000.)) <<
00092 " MB/s");
00093
00094 std::cout << *Stats;
00095 Stats->reset();
00096
00097 Stack.set_prefetch_aggr(DISKS * 8);
00098
00100 Timer.reset();
00101 Timer.start();
00102
00103 for (i = 0; i < ops; ++i)
00104 {
00105 Stack.pop();
00106 }
00107
00108 Timer.stop();
00109
00110 STXXL_MSG("Records in Stack: " << Stack.size());
00111 if (!Stack.empty())
00112 {
00113 STXXL_MSG("Stack must be empty");
00114 abort();
00115 }
00116
00117 STXXL_MSG("Deletions elapsed time: " << (Timer.mseconds() / 1000.) <<
00118 " seconds : " << (double(volume) / (1024. * 1024. * Timer.mseconds() / 1000.)) <<
00119 " MB/s");
00120
00121 std::cout << *Stats;
00122 }
00123
00124
00125 template <class my_record>
00126 void run_stxxl_normal_stack(stxxl::int64 volume)
00127 {
00128 typedef typename stxxl::STACK_GENERATOR<my_record, stxxl::external,
00129 stxxl::normal, DISKS, BLOCK_SIZE>::result stack_type;
00130 typedef typename stack_type::block_type block_type;
00131
00132 STXXL_MSG("Record size: " << sizeof(my_record) << " bytes");
00133
00134 stack_type Stack;
00135
00136 stxxl::int64 ops = volume / sizeof(my_record);
00137
00138 stxxl::int64 i;
00139
00140 my_record cur;
00141
00142 stxxl::stats * Stats = stxxl::stats::get_instance();
00143 Stats->reset();
00144
00145 stxxl::timer Timer;
00146 Timer.start();
00147
00148 for (i = 0; i < ops; ++i)
00149 {
00150 Stack.push(cur);
00151 }
00152
00153 Timer.stop();
00154
00155 STXXL_MSG("Records in Stack: " << Stack.size());
00156 if (i != Stack.size())
00157 {
00158 STXXL_MSG("Size does not match");
00159 abort();
00160 }
00161
00162 STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) <<
00163 " seconds : " << (double(volume) / (1024. * 1024. * Timer.mseconds() / 1000.)) <<
00164 " MB/s");
00165
00166 std::cout << *Stats;
00167 Stats->reset();
00168
00169
00171 Timer.reset();
00172 Timer.start();
00173
00174 for (i = 0; i < ops; ++i)
00175 {
00176 Stack.pop();
00177 }
00178
00179 Timer.stop();
00180
00181 STXXL_MSG("Records in Stack: " << Stack.size());
00182 if (!Stack.empty())
00183 {
00184 STXXL_MSG("Stack must be empty");
00185 abort();
00186 }
00187
00188 STXXL_MSG("Deletions elapsed time: " << (Timer.mseconds() / 1000.) <<
00189 " seconds : " << (double(volume) / (1024. * 1024. * Timer.mseconds() / 1000.)) <<
00190 " MB/s");
00191
00192 std::cout << *Stats;
00193 }
00194
00195
00196 int main(int argc, char * argv[])
00197 {
00198 STXXL_MSG("stxxl::pq block size: " << BLOCK_SIZE << " bytes");
00199
00200 #ifdef STXXL_DIRECT_IO_OFF
00201 STXXL_MSG("STXXL_DIRECT_IO_OFF is defined");
00202 #else
00203 STXXL_MSG("STXXL_DIRECT_IO_OFF is NOT defined");
00204 #endif
00205
00206 if (argc < 3)
00207 {
00208 STXXL_MSG("Usage: " << argv[0] << " version #volume");
00209 STXXL_MSG("\t version = 1: grow-shrink-stack2 with 4 byte records");
00210 STXXL_MSG("\t version = 2: grow-shrink-stack2 with 32 byte records");
00211 STXXL_MSG("\t version = 3: normal-stack with 4 byte records");
00212 STXXL_MSG("\t version = 4: normal-stack with 32 byte records");
00213 return -1;
00214 }
00215
00216 int version = atoi(argv[1]);
00217 stxxl::int64 volume = stxxl::atoint64(argv[2]);
00218
00219 STXXL_MSG("Allocating array with size " << MEM_2_RESERVE
00220 << " bytes to prevent file buffering.");
00221 int * array = new int[MEM_2_RESERVE / sizeof(int)];
00222 std::fill(array, array + (MEM_2_RESERVE / sizeof(int)), 0);
00223
00224 STXXL_MSG("Running version: " << version);
00225 STXXL_MSG("Data volume : " << volume << " bytes");
00226
00227 switch (version)
00228 {
00229 case 1:
00230 run_stxxl_growshrink2_stack<my_record_<4> >(volume);
00231 break;
00232 case 2:
00233 run_stxxl_growshrink2_stack<my_record_<32> >(volume);
00234 break;
00235 case 3:
00236 run_stxxl_normal_stack<my_record_<4> >(volume);
00237 break;
00238 case 4:
00239 run_stxxl_normal_stack<my_record_<32> >(volume);
00240 break;
00241 default:
00242 STXXL_MSG("Unsupported version " << version);
00243 }
00244
00245 delete[] array;
00246 }