Make ZC EM API pingpong benchmarks accept user params and add a warmup phase
[charm.git] / examples / charm++ / zerocopy / entry_method_api / unreg / pingpong / pingpong.C
1 #include "pingpong.decl.h"
2
3 CProxy_main mainProxy;
4 int minSize, maxSize, smallIter, bigIter;
5
6 #define P1 0
7 #define P2 1%CkNumPes()
8
9 class main : public CBase_main
10 {
11   CProxy_Ping1 arr1;
12   int size;
13   bool warmUp;
14 public:
15   main(CkMigrateMessage *m) {}
16   main(CkArgMsg *m)
17   {
18     if(CkNumPes()>2) {
19       CkAbort("Run this program on 1 or 2 processors only.\n");
20     }
21     if(m->argc == 5) {
22       minSize = atoi(m->argv[1])/2; // Start with a smaller size to run a warm up phase
23       maxSize = atoi(m->argv[2]);
24       smallIter = atoi(m->argv[3]);
25       bigIter = atoi(m->argv[4]);
26     } else if(m->argc == 1) {
27       // use defaults
28       minSize = 512; // Start with a smaller size to run a warm up phase before starting message size at 1024 bytes
29       maxSize = 1 << 25;
30       smallIter = 1000;
31       bigIter = 100;
32     } else {
33       CkPrintf("Usage: ./pingpong <min size> <max size> <small message iter> <big message iter>\n");
34       CkExit(1);
35     }
36     delete m;
37     size = minSize;
38     mainProxy = thisProxy;
39     warmUp = true;
40     CkPrintf("Size (bytes) \t\tIterations\t\tRegular API (one-way us)\tZero Copy API (one-way us)\n");
41     arr1 = CProxy_Ping1::ckNew(2);
42     CkStartQD(CkCallback(CkIndex_main::maindone(), mainProxy));
43   };
44
45   void maindone(void){
46     if(size <= maxSize) {
47       arr1[0].start(size, warmUp);
48       warmUp = false;
49       size = size << 1;
50     } else {
51         arr1[0].freeBuffer();
52     }
53   };
54 };
55
56
57 class Ping1 : public CBase_Ping1
58 {
59   int size;
60   int niter;
61   int iterations;
62   double start_time, end_time, reg_time, zerocpy_time;
63   char *nocopyMsg;
64
65 public:
66   Ping1()
67   {
68     nocopyMsg = new char[maxSize];
69     niter = 0;
70   }
71   Ping1(CkMigrateMessage *m) {}
72
73   void start(int size, bool warmUp)
74   {
75     niter = 0;
76     if(size >= 1 << 20)
77       iterations = bigIter;
78     else
79       iterations = smallIter;
80     start_time = CkWallTimer();
81     thisProxy[1].recv(nocopyMsg, size, warmUp);
82   }
83
84   void freeBuffer(){
85     delete [] nocopyMsg;
86     if(thisIndex == 0){
87       thisProxy[1].freeBuffer();
88     }
89     else{
90       CkExit();
91     }
92   }
93
94   void recv(char* msg, int size, bool warmUp)
95   {
96     if(thisIndex==0) {
97       niter++;
98       if(niter==iterations) {
99         end_time = CkWallTimer();
100         reg_time = 1.0e6*(end_time-start_time)/iterations;
101         niter = 0;
102         start_time = CkWallTimer();
103         thisProxy[1].recv_zerocopy(CkSendBuffer(nocopyMsg, CK_BUFFER_UNREG), size, warmUp);
104       } else {
105         thisProxy[1].recv(nocopyMsg, size, warmUp);
106       }
107     } else {
108       thisProxy[0].recv(nocopyMsg, size, warmUp);
109     }
110   }
111
112   void recv_zerocopy(char* msg, int size, bool warmUp)
113   {
114     if(thisIndex==0) {
115       niter++;
116       if(niter==iterations) {
117         end_time = CkWallTimer();
118         zerocpy_time = 1.0e6*(end_time-start_time)/iterations;
119         if(warmUp == false) {
120           if(size < 1 << 24)
121             CkPrintf("%d\t\t\t%d\t\t\t%lf\t\t\t%lf\n", size, iterations, reg_time/2, zerocpy_time/2);
122           else //using different print format for larger numbers for aligned output
123             CkPrintf("%d\t\t%d\t\t\t%lf\t\t\t%lf\n", size, iterations, reg_time/2, zerocpy_time/2);
124         }
125         niter=0;
126         mainProxy.maindone();
127       } else {
128         thisProxy[1].recv_zerocopy(CkSendBuffer(nocopyMsg, CK_BUFFER_UNREG), size, warmUp);
129       }
130     } else {
131       thisProxy[0].recv_zerocopy(CkSendBuffer(nocopyMsg, CK_BUFFER_UNREG), size, warmUp);
132     }
133   }
134 };
135
136 #include "pingpong.def.h"