a function to return Cray XE torus dimension
[charm.git] / tests / converse / commbench / memoryAccess.c
1 /***************************************************************************
2  *
3  *  Benchmark to measure performnce of CmiAlloc/CmiFree and traversals
4  *  of associated memory
5  *
6  *  Two types of benchmarking has been done-
7  *
8  *  1. A flurry of operations of same type and on same size
9  *
10  *  2. A random but commuatatively organized  mix of operations on a range
11  *     of data size.
12  *
13  *  Author- Nikhil Jain
14  *
15  ***************************************************************************/
16
17 #include <converse.h>
18 #include "commbench.h"
19
20 #define CLUBMALLOC 1000
21 #define RANDMALLOC 1000
22 #define RANDOPS 1000
23 //#define POWER 15
24 //#define MAXSIZE 16384
25 #define POWER 20 
26 #define MAXSIZE 1024*1024
27 typedef double myType;
28 myType value = 10;
29 int dist[] = {1,5,9,10};
30
31 CpvStaticDeclare(int, memoryIdx);
32
33 double memoryTest(){
34   double starttime, endtime;  
35   double extraOverhead;
36   myType **ptrs = NULL;
37   int i,j,k,size;
38   myType sums[200];
39   double times[POWER][4];
40   int sizes[RANDMALLOC];
41   int ops[RANDOPS][3];
42
43   ptrs = (myType **)malloc(CLUBMALLOC*sizeof(myType *));
44   for(i=0; i<CLUBMALLOC; i++) ptrs[i] = 0;
45   starttime = CmiWallTimer();
46   for(i=0; i<CLUBMALLOC; i++) ptrs[i] = (myType *)0xabcd;
47   endtime = CmiWallTimer();
48   extraOverhead = endtime - starttime;
49   
50   size = 1;
51   for(i = 0; i < POWER; i++,size*=2) {
52
53     for(j=0; j<CLUBMALLOC; j++) ptrs[j] = 0;
54     starttime = CmiWallTimer();
55     for(j=0; j<CLUBMALLOC; j++) {
56       ptrs[j] = (myType *)CmiAlloc(size*sizeof(myType));
57     }
58     endtime = CmiWallTimer();
59     times[i][0] = endtime - starttime - extraOverhead;
60     
61     for(j=0; j<CLUBMALLOC; j++) {
62       for(k = 0; k < size; k++) {
63         ptrs[j][k] = value;
64       }
65     }
66
67     starttime = CmiWallTimer();
68     for(j=0; j<CLUBMALLOC; j++) {
69       for(k = 0; k < size; k++) {
70         ptrs[j][k] = value;
71       }
72     }
73     endtime = CmiWallTimer();
74     times[i][1] = endtime - starttime - extraOverhead;
75
76     for(j = 0; j < 200; j++) {
77       sums[j] = 0;
78     }
79
80     starttime = CmiWallTimer();
81     for(j=0; j<CLUBMALLOC; j++) {
82       for(k = 0; k < size; k++) {
83         sums[k%200] += ptrs[j][k];
84       }
85     }
86     endtime = CmiWallTimer();
87     times[i][2] = endtime - starttime - extraOverhead;
88
89     starttime = CmiWallTimer();
90     for(j=0; j<CLUBMALLOC; j++) CmiFree(ptrs[j]);
91     endtime = CmiWallTimer();
92     times[i][3] = endtime - starttime - extraOverhead;
93   }
94
95   if(CmiMyPe()==0){
96     CmiPrintf("Performance number of clubbed malloc-traversal-free\n");
97     CmiPrintf("Size\tIterations\tMalloc\tWrite\tRead\tFree\n");
98     size = 1;
99     for(i = 0; i < POWER; i++,size*=2) {
100       CmiPrintf("%d\t%d\t%E\t%E\t%E\t%E\n",size,CLUBMALLOC,times[i][0],
101                times[i][1],times[i][2],times[i][3]);
102     }
103   }
104
105   free(ptrs);
106   ptrs = (myType **)malloc(RANDMALLOC*sizeof(myType *));
107
108   srand(7187);
109   for(i=0; i<RANDMALLOC; i++) {
110     sizes[i] = rand() % MAXSIZE;
111   }
112
113   for(i=0; i<RANDMALLOC; i++) {
114       ptrs[i] = (myType *)CmiAlloc(sizes[i]*sizeof(myType));
115   }
116
117   for(i=0; i<RANDOPS; i++) {
118     ops[i][0] = rand()%RANDMALLOC;
119     ops[i][1] = rand()%dist[3];
120     if(ops[i][1] < dist[0]) {
121       ops[i][1] = 0;
122       ops[i][2] =rand()%MAXSIZE;
123     } else if(ops[i][1] < dist[1]) {
124       ops[i][1] = 1;
125       ops[i][2] = sizes[ops[i][0]];
126     } if(ops[i][1] < dist[2]) {
127       ops[i][1] = 2;
128       ops[i][2] = sizes[ops[i][0]];
129     } else {
130       ops[i][1] = 3;
131     }
132   }
133
134   starttime = CmiWallTimer();
135   for(i=0; i<RANDOPS; i++) {
136     switch(ops[i][1]) {
137       case 0:
138         if(ptrs[ops[i][0]] != NULL)
139           CmiFree(ptrs[ops[i][0]]);
140         ptrs[ops[i][0]] = (myType *)CmiAlloc(ops[i][2]*sizeof(myType));
141         break;
142       case 1:
143         if(ptrs[ops[i][0]] == NULL)
144           ptrs[ops[i][0]] = (myType *)CmiAlloc(ops[i][2]*sizeof(myType));
145         for(j = 0; j < ops[i][2]; j++) {
146           ptrs[ops[i][0]][j] = value;
147         }
148         break;
149      case 2:
150         if(ptrs[ops[i][0]] == NULL)
151           ptrs[ops[i][0]] = (myType *)CmiAlloc(ops[i][2]*sizeof(myType));
152         for(j = 0; j < ops[i][2]; j++) {
153           sums[k%200] += ptrs[ops[i][0]][j];
154         }
155         break;
156     case 3:
157       if(ptrs[ops[i][0]] != NULL){
158         CmiFree(ptrs[ops[i][0]]);
159         ptrs[ops[i][0]] = NULL;
160       }
161     }
162   }
163   endtime = CmiWallTimer();
164
165   if(CmiMyPe()==0){
166     CmiPrintf("Time taken by random malloc-traversal-free benchmark with following commutative distribution: malloc %d, write %d, read %d, free %d, max malloc size %d, length of table %d, number of ops %d is %E.\n",dist[0],dist[1],dist[2],dist[3],MAXSIZE,RANDMALLOC,RANDOPS, (endtime-starttime));
167   }
168
169   for(i=0; i<RANDMALLOC; i++) {
170     if(ptrs[i] != NULL)
171       CmiFree(ptrs[i]);
172   }
173   free(ptrs);
174 }
175
176 static void memoryHandler(EmptyMsg *msg){
177         /* Make sure the memory contention on a node happens roughly at the same time */
178         CmiNodeBarrier();
179         memoryTest();   
180         CmiNodeBarrier();
181         
182         if(CmiMyPe()==0){
183     CmiSetHandler(msg, CpvAccess(ack_handler));
184     CmiSyncSend(0, sizeof(EmptyMsg), msg);
185         }
186         else {
187           CmiFree(msg);
188         }
189 }
190
191 void memoryAccess_init(void)
192 {
193   EmptyMsg msg;
194
195   CmiPrintf("Single core malloc/free/traversal performance numbers\n");
196   memoryTest();
197              
198   CmiPrintf("Multi core malloc/free/traversal performance numbers\n");
199   CmiSetHandler(&msg, CpvAccess(memoryIdx));
200   CmiSyncBroadcastAll(sizeof(EmptyMsg), &msg);
201 }
202
203 void memoryAccess_moduleinit(void)
204 {
205   CpvInitialize(int, memoryIdx);
206   CpvAccess(memoryIdx) = CmiRegisterHandler((CmiHandler)memoryHandler);
207 }
208