20 #include <ndb_global.h>
28 #include <NdbTimer.hpp>
29 #include <NDBT_Stats.hpp>
30 #include <NDBT_ReturnCodes.h>
37 static const int NP_Insert = 0;
38 static const int NP_Update = 1;
39 static const int NP_WriteUpdate = 2;
40 static const int NP_WriteInsert = 3;
41 static const int NP_Delete = 4;
42 static const int NP_BulkRead = 5;
43 static const int NP_MAX = 5;
45 static const char * Operations[] = {
57 static int NoOfTransactions = 10000;
58 static int ParallellTransactions = 1000;
59 static int OperationsPerTransaction = 10;
60 static int NoOfColumns = 20;
61 static int BytesPerInsert = 300;
62 static int BytesPerUpdate = 200;
63 static int LoopCount = 10;
68 static char TableName[255];
74 static char * TestData;
82 static void sequence(
int loops);
84 inline void * getPtr(
int rowNo) {
return TestData+rowNo*BytesPerInsert;}
85 inline void setPK(
int rowNo,
int pk){ * (
int *)getPtr(rowNo) = pk; }
87 static void SetupTestData();
88 static void CleanupTestData();
90 static bool CreateTable();
91 static bool CleanTable();
92 static bool CreateBindings();
99 int ForceSend, Interval;
103 ndbout <<
"newtonPerf" << endl
104 <<
" -n Transactions per loop and operation ("
105 << NoOfTransactions <<
")" << endl
106 <<
" -p parallell transactions (" << ParallellTransactions <<
")"
108 <<
" -o operations per transaction (" << OperationsPerTransaction
110 <<
" -a no of columns (" << NoOfColumns <<
")" << endl
111 <<
" -b Table size in bytes (" << BytesPerInsert <<
")" << endl
112 <<
" -u Bytes per update (" << BytesPerUpdate <<
")" << endl
113 <<
" -l Loop count (" << LoopCount <<
")" << endl
114 <<
" -i Interval (" << Interval <<
"ms)" << endl
115 <<
" -f Force send algorithm (" << ForceSend <<
")" << endl
116 <<
" -h Help" << endl;
122 parseArgs(
int argc,
const char **argv){
123 bool a =
false, b =
false, u =
false;
125 for(
int i = 1;
i<argc;
i++){
126 if(argv[
i][0] !=
'-'){
127 ndbout <<
"Invalid argument: " << argv[
i] << endl;
131 if(argv[
i][1] ==
'h')
135 ndbout <<
"Expecting argument to " << argv[
i] << endl;
141 NoOfTransactions = atoi(argv[i+1]);
144 ParallellTransactions = atoi(argv[i+1]);
147 OperationsPerTransaction = atoi(argv[i+1]);
150 NoOfColumns = atoi(argv[i+1]);
154 BytesPerInsert = atoi(argv[i+1]);
158 BytesPerUpdate = atoi(argv[i+1]);
162 LoopCount = atoi(argv[i+1]);
166 const int val = atoi(argv[i+1]);
168 ndbout <<
"Invalid force send algorithm: "
177 const int val = atoi(argv[i+1]);
179 ndbout <<
"Invalid NBP interval: "
187 ndbout <<
"Invalid option: " << argv[
i] << endl;
192 if(a && !b) BytesPerInsert = 15 * NoOfColumns;
193 if(!a && b) NoOfColumns = ((BytesPerInsert + 14) / 15)+1;
196 BytesPerUpdate = (2 * BytesPerInsert) / 3;
199 if(NoOfColumns < 2) t =
false;
200 if(BytesPerInsert < 8) t =
false;
201 if(BytesPerUpdate < 8) t =
false;
204 ndbout <<
"Invalid arguments combination of -a -b -u not working out"
211 NDB_COMMAND(newton_perf,
"newton_perf",
212 "newton_perf",
"newton_perf", 65535){
214 if(!parseArgs(argc, argv)){
216 return NDBT_ProgramExit(NDBT_WRONGARGS);
219 ndbout <<
"-----------" << endl;
233 if(!CreateBindings()){
253 ErrorMsg(
const char * s){
263 const int j = i - (i & 3);
270 ndbout <<
"Creating testdata" << endl;
275 const int sz = m4((BytesPerInsert - ((NoOfColumns+1)/2)*4)/(NoOfColumns/2));
277 UpdateBindingColumns = 0;
278 for(
int i = 0; i<NoOfColumns; i++){
281 sprintf(tmp,
"I%d", i);
283 ColumnDescriptions[
i].
Size = 4;
286 sprintf(tmp,
"S%d", i);
288 ColumnDescriptions[
i].
Size = sz;
291 ColumnDescriptions[
i].
IsKey = 0;
292 ColumnDescriptions[
i].
Name = strdup(tmp);
294 InsertBindings[
i].
Name = strdup(tmp);
296 InsertBindings[
i].
Size = ColumnDescriptions[
i].
Size;
297 InsertBindings[
i].
Offset = sum - ColumnDescriptions[
i].
Size;
298 InsertBindings[
i].
Ptr = 0;
300 if(sum <= BytesPerUpdate)
301 UpdateBindingColumns++;
303 if(UpdateBindingColumns == 1)
304 UpdateBindingColumns++;
306 ColumnDescriptions[0].
IsKey = 1;
308 assert(sum <= BytesPerInsert);
309 sprintf(TableName,
"NEWTON_%d_%d", sum, NoOfColumns);
312 memcpy(UpdateBindings, InsertBindings,
316 memcpy(DeleteBindings, InsertBindings,
319 TestData = (
char *)malloc(NoOfTransactions *
320 OperationsPerTransaction * BytesPerInsert);
322 assert(TestData != 0);
323 for(
int i = 0; i<NoOfTransactions; i++)
324 for(
int j = 0; j<OperationsPerTransaction; j++){
325 const int pk = i * OperationsPerTransaction + j;
334 for(
int i = 0; i<NoOfColumns; i++){
335 free((
char*)ColumnDescriptions[i].Name);
336 free((
char*)InsertBindings[i].Name);
338 delete [] ColumnDescriptions;
339 delete [] InsertBindings;
340 delete [] UpdateBindings;
341 delete [] DeleteBindings;
345 static bool CleanReturnValue =
true;
346 static int CleanCallbacks = 0;
347 static int CleanRows = 0;
360 ndbout <<
"Cleaning table..." << flush;
361 CleanReturnValue =
true;
364 for(
int i = 0; i<NoOfTransactions * OperationsPerTransaction; i++){
368 while((i-CleanCallbacks)>ParallellTransactions)
369 NdbSleep_MilliSleep(100);
371 while(CleanCallbacks != (NoOfTransactions * OperationsPerTransaction))
372 NdbSleep_SecSleep(1);
374 ndbout << CleanRows <<
" rows deleted" << endl;
376 return CleanReturnValue;
382 ndbout <<
"Creating bindings" << endl;
383 InsertB = UpdateB = DeleteB = 0;
386 InsertBindings, BytesPerInsert);
388 ErrorMsg(
"Failed to create insert bindings");
393 UpdateBindings, BytesPerInsert);
395 ErrorMsg(
"Failed to create update bindings");
401 DeleteBindings, BytesPerInsert);
403 ErrorMsg(
"Failed to create delete bindings");
414 ndbout <<
"Creating " << TableName << endl;
425 static int CurrentOp = NP_Insert;
426 static int SequenceSent = 0;
427 static int SequenceRecv = 0;
433 static int * ReqHashPos;
435 static int SequenceLatencyPos;
436 static NDB_TICKS * StartTime;
441 computeHashMax(
int elements){
443 while(HashMax < elements)
456 int r = (request >> 2) & (HashMax-1);
465 int i = hash(request);
467 while(ReqHash[i] != 0)
468 i = ((i + 1) & (HashMax-1));
470 ReqHash[
i] = request;
479 int i = hash(request);
481 while(ReqHash[i] != request)
482 i = ((i + 1) & (HashMax-1));
486 return ReqHashPos[
i];
492 int p = getRequest(reqId) - 1;
495 ndbout <<
"p = " << p << endl;
496 ndbout <<
"DBA_GetErrorMsg(" << error <<
") = "
498 ndbout <<
"DBA_GetNdbErrorMsg(" << ec <<
") = "
505 if(SequenceRecv == NoOfTransactions){
506 SequenceTimer.doStop();
509 if((p & 127) == 127){
510 NDB_TICKS t = NdbTick_CurrentMillisecond() - StartTime[p];
511 SequenceLatency[CurrentOp].addObservation(t);
523 return a > b ? b : a;
528 SequenceOp(DBA_ArrayFunction func,
const DBA_Binding_t* pBindings,
int op){
531 SequenceLatencyPos = 1;
534 SequenceTimer.doStart();
535 for(
int i = 0; i<NoOfTransactions; ){
536 const int l1 = ParallellTransactions - (SequenceSent - SequenceRecv);
537 const int l2 = min(NoOfTransactions - i, l1);
538 for(
int j = 0; j<l2; j++){
540 getPtr(i*OperationsPerTransaction),
541 OperationsPerTransaction,
545 addRequest(r, i + 1);
548 if((SequenceSent & 127) == 127){
549 NDB_TICKS t = NdbTick_CurrentMillisecond();
554 NdbSleep_MilliSleep(10);
557 while(SequenceRecv != SequenceSent)
558 NdbSleep_SecSleep(1);
560 ndbout <<
"Performed " << NoOfTransactions <<
" " << Operations[op]
563 double p = NoOfTransactions * 1000;
564 double t = SequenceTimer.elapsedTime();
565 double o = p * OperationsPerTransaction;
591 b *= NoOfTransactions * OperationsPerTransaction;
595 SequenceStats[op][0].addObservation(t);
596 SequenceStats[op][1].addObservation(p);
597 SequenceStats[op][2].addObservation(o);
598 SequenceStats[op][3].addObservation(b);
600 int t2 = SequenceStats[op][0].getMean();
601 int p2 = SequenceStats[op][1].getMean();
602 int o2 = SequenceStats[op][2].getMean();
603 int b2 = SequenceStats[op][3].getMean();
605 ndbout << SequenceTimer.elapsedTime() <<
"(" << t2 <<
")ms";
606 ndbout <<
" -> " << _p <<
"(" << p2 <<
") T/s - " << _o
607 <<
"(" << o2 <<
") O/s - " << _b <<
"(" << b2 <<
") Kb/s" << endl;
609 ndbout <<
" Latency (ms) Avg: " << (int)SequenceLatency[op].getMean()
610 <<
" min: " << (int)SequenceLatency[op].getMin()
611 <<
" max: " << (int)SequenceLatency[op].getMax()
612 <<
" stddev: " << (int)SequenceLatency[op].getStddev()
613 <<
" n: " << SequenceLatency[op].getCount() << endl;
622 computeHashMax(ParallellTransactions);
624 ReqHashPos =
new int[HashMax];
625 StartTime =
new NDB_TICKS[NoOfTransactions];
627 for(
int i = 0; i<NP_MAX; i++){
628 SequenceLatency[
i].reset();
629 for(
int j = 0; j<4; j++)
630 SequenceStats[i][j].reset();
632 for(
int i = 0; i<loops; i++){
633 ndbout <<
"Loop #" << (i+1) << endl;
643 ndbout <<
"-------------------" << endl << endl;
647 delete [] ReqHashPos;