MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bench_pool.cpp
1 /*
2  Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include "ArrayPool.hpp"
20 #include "WOPool.hpp"
21 #include "RWPool.hpp"
22 #include <NdbTick.h>
23 #include "ndbd_malloc_impl.hpp"
24 #include "SimulatedBlock.hpp"
25 
26 #ifdef USE_CALLGRIND
27 #include <valgrind/callgrind.h>
28 #else
29 #define CALLGRIND_TOGGLE_COLLECT()
30 #endif
31 
32 #define T_TEST_AP (1 << 0)
33 #define T_TEST_WO (1 << 1)
34 #define T_TEST_RW (1 << 2)
35 
36 #define T_SEIZE (1 << 0)
37 #define T_RELEASE (1 << 1)
38 #define T_G_RELEASE (1 << 2)
39 #define T_R_RELEASE (1 << 3)
40 #define T_R_G_RELEASE (1 << 4)
41 #define T_MIX (1 << 5)
42 #define T_GETPTR (1 << 6)
43 #define T_FIFO (1 << 7)
44 
45 const char *test_names[] = {
46  "seize",
47  "release",
48  "get+rel",
49  "r-rel",
50  "r-get+rel",
51  "mix",
52  "getptr",
53  "fifo",
54  0
55 };
56 
57 Uint32 pools = ~0;
58 Uint32 tests = ~0;
59 Uint32 records = ~0;
60 Uint32 sizes = 7;
61 unsigned int seed;
63 Configuration cfg;
64 Block_context ctx(cfg, mm);
65 struct BB : public SimulatedBlock
66 {
67  BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {}
68 };
69 
70 BB block(DBACC, ctx);
71 
72 template <typename T>
73 void
74 init(ArrayPool<T> & pool, Uint32 cnt)
75 {
76  pool.setSize(cnt + 1, true);
77 }
78 
79 template <typename T>
80 void
81 init(RecordPool<T, WOPool> & pool, Uint32 cnt)
82 {
83  Pool_context pc;
84  pc.m_block = &block;
85  pool.wo_pool_init(0x2001, pc);
86 }
87 
88 template <typename T>
89 void
90 init(RecordPool<T, RWPool> & pool, Uint32 cnt)
91 {
92  Pool_context pc;
93  pc.m_block = &block;
94  pool.init(0x2001, pc);
95 }
96 
97 template <typename T, typename R>
98 void
99 test_pool(R& pool, Uint32 cnt, Uint32 loops)
100 {
101  Ptr<T> ptr;
102  Uint32 *arr = (Uint32*)alloca(cnt * sizeof(Uint32));
103  memset(arr, 0, cnt * sizeof(Uint32));
104  if (tests & T_SEIZE)
105  {
106  Uint64 sum = 0;
107  for(Uint32 i = 0; i<loops; i++)
108  { // seize
109  Uint64 start = NdbTick_CurrentMillisecond();
110  CALLGRIND_TOGGLE_COLLECT();
111  for(Uint32 j = 0; j<cnt; j++)
112  {
113  bool b = pool.seize(ptr);
114  arr[j] = ptr.i;
115  ptr.p->do_stuff();
116  assert(b);
117  }
118  CALLGRIND_TOGGLE_COLLECT();
119  Uint64 stop = NdbTick_CurrentMillisecond();
120 
121  for(Uint32 j = 0; j<cnt; j++)
122  {
123  ptr.i = arr[j];
124  pool.getPtr(ptr);
125  ptr.p->do_stuff();
126  pool.release(ptr.i);
127  arr[j] = RNIL;
128  }
129  sum += (stop - start);
130  }
131  printf(" ; %lld", sum); fflush(stdout);
132  }
133 
134  if (tests & T_RELEASE)
135  { // release
136  Uint64 sum = 0;
137  for(Uint32 i = 0; i<loops; i++)
138  {
139  for(Uint32 j = 0; j<cnt; j++)
140  {
141  bool b = pool.seize(ptr);
142  arr[j] = ptr.i;
143  ptr.p->do_stuff();
144  }
145 
146  Uint64 start = NdbTick_CurrentMillisecond();
147  CALLGRIND_TOGGLE_COLLECT();
148  for(Uint32 j = 0; j<cnt; j++)
149  {
150  pool.release(arr[j]);
151  arr[j] = RNIL;
152  }
153  CALLGRIND_TOGGLE_COLLECT();
154  Uint64 stop = NdbTick_CurrentMillisecond();
155 
156  sum += (stop - start);
157  }
158  printf(" ; %lld", sum); fflush(stdout);
159  }
160 
161  if (tests & T_G_RELEASE)
162  { // getptr + release
163  Uint64 sum = 0;
164  for(Uint32 i = 0; i<loops; i++)
165  {
166  for(Uint32 j = 0; j<cnt; j++)
167  {
168  bool b = pool.seize(ptr);
169  arr[j] = ptr.i;
170  ptr.p->do_stuff();
171  }
172 
173  Uint64 start = NdbTick_CurrentMillisecond();
174  CALLGRIND_TOGGLE_COLLECT();
175  for(Uint32 j = 0; j<cnt; j++)
176  {
177  pool.getPtr(ptr, arr[j]);
178  ptr.p->do_stuff();
179  pool.release(ptr);
180  arr[j] = RNIL;
181  }
182  CALLGRIND_TOGGLE_COLLECT();
183  Uint64 stop = NdbTick_CurrentMillisecond();
184 
185  sum += (stop - start);
186  }
187  printf(" ; %lld", sum); fflush(stdout);
188  }
189 
190  if (tests & T_R_RELEASE)
191  { // release reverse
192  Uint64 sum = 0;
193  for(Uint32 i = 0; i<loops; i++)
194  {
195  for(Uint32 j = 0; j<cnt; j++)
196  {
197  bool b = pool.seize(ptr);
198  arr[j] = ptr.i;
199  ptr.p->do_stuff();
200  }
201 
202  Uint64 start = NdbTick_CurrentMillisecond();
203  CALLGRIND_TOGGLE_COLLECT();
204  for(Uint32 j = 0; j<cnt; j++)
205  {
206  pool.release(arr[cnt - j - 1]);
207  arr[cnt - j - 1] = RNIL;
208  }
209  CALLGRIND_TOGGLE_COLLECT();
210  Uint64 stop = NdbTick_CurrentMillisecond();
211 
212  sum += (stop - start);
213  }
214  printf(" ; %lld", sum); fflush(stdout);
215  }
216 
217  if (tests & T_R_G_RELEASE)
218  { // getptr + release
219  Uint64 sum = 0;
220  for(Uint32 i = 0; i<loops; i++)
221  {
222  for(Uint32 j = 0; j<cnt; j++)
223  {
224  bool b = pool.seize(ptr);
225  arr[j] = ptr.i;
226  ptr.p->do_stuff();
227  }
228 
229  Uint64 start = NdbTick_CurrentMillisecond();
230  CALLGRIND_TOGGLE_COLLECT();
231  for(Uint32 j = 0; j<cnt; j++)
232  {
233  pool.getPtr(ptr, arr[cnt - j - 1]);
234  ptr.p->do_stuff();
235  pool.release(ptr);
236  arr[cnt - j - 1] = RNIL;
237  }
238  CALLGRIND_TOGGLE_COLLECT();
239  Uint64 stop = NdbTick_CurrentMillisecond();
240 
241  sum += (stop - start);
242  }
243  printf(" ; %lld", sum); fflush(stdout);
244  }
245 
246  if (tests & T_MIX)
247  {
248  Uint64 sum = 0;
249  Uint64 start = NdbTick_CurrentMillisecond();
250  Uint32 lseed = seed;
251  CALLGRIND_TOGGLE_COLLECT();
252  for(Uint32 i = 0; i<loops * cnt; i++)
253  {
254  int pos = rand_r(&lseed) % cnt;
255  ptr.i = arr[pos];
256  if (ptr.i == RNIL)
257  {
258  pool.seize(ptr);
259  arr[pos] = ptr.i;
260  assert(ptr.i != RNIL);
261  ptr.p->do_stuff();
262  }
263  else
264  {
265  pool.getPtr(ptr);
266  ptr.p->do_stuff();
267  pool.release(ptr);
268  arr[pos] = RNIL;
269  }
270  }
271  CALLGRIND_TOGGLE_COLLECT();
272  Uint64 stop = NdbTick_CurrentMillisecond();
273 
274  for(Uint32 j = 0; j<cnt; j++)
275  {
276  ptr.i = arr[j];
277  if (ptr.i != RNIL)
278  {
279  pool.getPtr(ptr);
280  pool.release(ptr.i);
281  }
282  arr[j] = RNIL;
283  }
284 
285  sum += (stop - start);
286  printf(" ; %lld", sum); fflush(stdout);
287  }
288 
289  if (tests & T_GETPTR)
290  {
291  Uint32 lseed = seed;
292  for(Uint32 j = 0; j<cnt; j++)
293  {
294  bool b = pool.seize(ptr);
295  arr[j] = ptr.i;
296  ptr.p->do_stuff();
297  assert(b);
298  }
299 
300  Uint64 sum = 0;
301  Uint64 start = NdbTick_CurrentMillisecond();
302  CALLGRIND_TOGGLE_COLLECT();
303  for(Uint32 i = 0; i<loops * cnt; i++)
304  {
305  int pos = rand_r(&lseed) % cnt;
306  ptr.i = arr[pos];
307  pool.getPtr(ptr);
308  ptr.p->do_stuff();
309  }
310  CALLGRIND_TOGGLE_COLLECT();
311  Uint64 stop = NdbTick_CurrentMillisecond();
312 
313  for(Uint32 j = 0; j<cnt; j++)
314  {
315  ptr.i = arr[j];
316  pool.getPtr(ptr);
317  ptr.p->do_stuff();
318  pool.release(ptr.i);
319  arr[j] = RNIL;
320  }
321 
322  sum += (stop - start);
323  printf(" ; %lld", sum); fflush(stdout);
324  }
325 
326  if (tests & T_FIFO)
327  { // fifo
328  Uint64 sum = 0;
329  Uint64 start = NdbTick_CurrentMillisecond();
330  CALLGRIND_TOGGLE_COLLECT();
331  for(Uint32 i = 0; i<loops; i++)
332  {
333  Uint32 head = RNIL;
334  Uint32 last = RNIL;
335 
336  Uint64 sum = 0;
337  for(Uint32 j = 0; j<cnt; j++)
338  {
339  pool.seize(ptr);
340  ptr.p->do_stuff();
341  ptr.p->m_nextList = RNIL;
342  if (head == RNIL)
343  {
344  head = ptr.i;
345  }
346  else
347  {
348  T* t = pool.getPtr(last);
349  t->m_nextList = ptr.i;
350  }
351  last = ptr.i;
352  }
353 
354  while (head != RNIL)
355  {
356  pool.getPtr(ptr, head);
357  ptr.p->do_stuff();
358  head = ptr.p->m_nextList;
359  pool.release(ptr);
360  }
361  }
362  CALLGRIND_TOGGLE_COLLECT();
363  Uint64 stop = NdbTick_CurrentMillisecond();
364  sum += (stop - start);
365  printf(" ; %lld", sum); fflush(stdout);
366  }
367 
368  ndbout_c("");
369 }
370 
371 template <Uint32 sz>
372 struct Rec {
373  Uint32 m_data;
374  Uint32 m_magic;
375  Uint32 nextPool;
376  Uint32 m_nextList;
377  char m_cdata[sz-16];
378 
379  void do_stuff() {
380  Uint32 sum = 0;
381  Uint32 *ptr = (Uint32*)this;
382  for(Uint32 i = 0; i<(sz >> 2); i++)
383  sum += * ptr ++;
384  m_data = sum;
385  }
386 };
387 
388 typedef Rec<32> Rec32;
389 typedef Rec<36> Rec36;
390 typedef Rec<56> Rec56;
391 typedef Rec<224> Rec224;
392 
393 template <typename T>
394 void test_ap(Uint32 cnt, Uint32 loop)
395 {
396  printf("AP ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
397  ArrayPool<T> pool;
398  init(pool, cnt);
399  test_pool<T, ArrayPool<T> >(pool, cnt, loop);
400 }
401 
402 template <typename T>
403 void test_rw(Uint32 cnt, Uint32 loop)
404 {
405  printf("RW ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
407  init(pool, cnt);
408  test_pool<T, RecordPool<T, RWPool> >(pool, cnt, loop);
409 }
410 
411 template <typename T>
412 void test_wo(Uint32 cnt, Uint32 loop)
413 {
414  printf("WO ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
416  init(pool, cnt);
417  test_pool<T, RecordPool<T, WOPool> >(pool, cnt, loop);
418 }
419 
420 #include <EventLogger.hpp>
421 extern EventLogger * g_eventLogger;
422 
423 int
424 main(int argc, char **argv)
425 {
426  Uint32 loops = 300000;
427  for (Uint32 i = 1 ; i<argc ; i++)
428  {
429  if (argc > i+1 && strcmp(argv[i], "-pools") == 0)
430  {
431  pools = 0;
432  for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
433  {
434  char c = argv[i+1][j];
435  if (c >= '0' && c <= '9')
436  pools |= 1 << (c - '0');
437  else
438  pools |= 1 << (10 + (c - 'a'));
439  }
440  }
441  else if (argc > i+1 && strcmp(argv[i], "-tests") == 0)
442  {
443  tests = 0;
444  for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
445  {
446  char c = argv[i+1][j];
447  if (c >= '0' && c <= '9')
448  tests |= 1 << (c - '0');
449  else
450  tests |= 1 << (10 + (c - 'a'));
451  }
452  }
453  else if (argc > i+1 && strcmp(argv[i], "-sizes") == 0)
454  {
455  sizes = 0;
456  for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
457  {
458  char c = argv[i+1][j];
459  if (c >= '0' && c <= '9')
460  sizes |= 1 << (c - '0');
461  else
462  sizes |= 1 << (10 + (c - 'a'));
463  }
464  }
465  else if (argc > i+1 && strcmp(argv[i], "-records") == 0)
466  {
467  records = 0;
468  for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
469  {
470  char c = argv[i+1][j];
471  if (c >= '0' && c <= '9')
472  records |= 1 << (c - '0');
473  else
474  records |= 1 << (10 + (c - 'a'));
475  }
476  }
477  else if (argc > i+1 && strcmp(argv[i], "-loop") == 0)
478  {
479  loops = atoi(argv[i+1]);
480  }
481  }
482 
483  Resource_limit rl;
484  rl.m_min = 0;
485  rl.m_max = 10000;
486  rl.m_resource_id = 0;
487  mm.set_resource_limit(rl);
488  if(!mm.init())
489  {
490  abort();
491  }
492 
493  seed = time(0);
494  Uint32 sz = 0;
495  Uint32 cnt = 256;
496 
497  printf("pool ; rs ; ws");
498  for (Uint32 i = 0; test_names[i] && i<31; i++)
499  if (tests & (1 << i))
500  printf(" ; %s", test_names[i]);
501  ndbout_c("");
502 
503  while(cnt <= 1000000)
504  {
505  Uint32 loop = 768 * loops / cnt;
506  if (sizes & (1 << sz))
507  {
508  if (records & 1)
509  {
510  if (pools & T_TEST_AP)
511  test_ap<Rec32>(cnt, loop);
512  if (pools & T_TEST_WO)
513  test_wo<Rec32>(cnt, loop);
514  if (pools & T_TEST_RW)
515  test_rw<Rec32>(cnt, loop);
516  }
517  if (records & 2)
518  {
519  if (pools & T_TEST_AP)
520  test_ap<Rec36>(cnt, loop);
521  if (pools & T_TEST_WO)
522  test_wo<Rec36>(cnt, loop);
523  if (pools & T_TEST_RW)
524  test_rw<Rec36>(cnt, loop);
525  }
526  if (records & 4)
527  {
528  if (pools & T_TEST_AP)
529  test_ap<Rec56>(cnt, loop);
530  if (pools & T_TEST_WO)
531  test_wo<Rec56>(cnt, loop);
532  if (pools & T_TEST_RW)
533  test_rw<Rec56>(cnt, loop);
534  }
535  if (records & 8)
536  {
537  if (pools & T_TEST_AP)
538  test_ap<Rec224>(cnt, loop);
539  if (pools & T_TEST_WO)
540  test_wo<Rec224>(cnt, loop);
541  if (pools & T_TEST_RW)
542  test_rw<Rec224>(cnt, loop);
543  }
544  }
545 
546  cnt += (512 << sz);
547  sz++;
548  }
549 }
550 
551 Uint32 g_currentStartPhase;
552 Uint32 g_start_type;
553 NdbNodeBitmask g_nowait_nodes;
554 
555 void
556 UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
557 }
558 
559 void
560 UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){
561 }
562 
563 void
564 UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){
565 }
566 
567 void
568 UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){
569 }
570 
571 #include <SimBlockList.hpp>
572 
573 void
574 SimBlockList::unload()
575 {
576 
577 }
578 
579 #define INSTANCE(X) \
580 template void test_ap<X>(unsigned, unsigned);\
581 template void test_wo<X>(unsigned, unsigned);\
582 template void test_rw<X>(unsigned, unsigned);\
583 template void test_pool<X, ArrayPool<X> >(ArrayPool<X>&, unsigned, unsigned);\
584 template void test_pool<X, RecordPool<X, RWPool> >(RecordPool<X, RWPool>&, unsigned, unsigned); \
585 template void test_pool<X, RecordPool<X, WOPool> >(RecordPool<X, WOPool>&, unsigned, unsigned);\
586 template void init<X>(ArrayPool<X>&, unsigned);\
587 template void init<X>(RecordPool<X, RWPool>&, unsigned);\
588 template void init<X>(RecordPool<X, WOPool>&, unsigned)
589 
590 INSTANCE(Rec32);
591 INSTANCE(Rec36);
592 INSTANCE(Rec56);
593 INSTANCE(Rec224);
594