Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mv msg/msg.h simgrid/msg.h
[simgrid.git] / examples / msg / cloud / multicore.c
1 /* Copyright (c) 2007-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <stdio.h>
8 #include "simgrid/msg.h"
9 #include "xbt/sysdep.h"         /* calloc, printf */
10
11 /* Create a log channel to have nice outputs. */
12 #include "xbt/log.h"
13 #include "xbt/asserts.h"
14 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
15
16
17
18
19
20 static int worker_main(int argc, char *argv[])
21 {
22   msg_task_t task = MSG_process_get_data(MSG_process_self());
23   MSG_task_execute(task);
24
25   XBT_INFO("task %p bye", task);
26
27   return 0;
28 }
29
30
31 struct task_data {
32         msg_task_t task;
33         double prev_computation_amount;
34         double prev_clock;
35 };
36
37
38 static void task_data_init_clock(struct task_data *t)
39 {
40   t->prev_computation_amount = MSG_task_get_remaining_computation(t->task);
41   t->prev_clock = MSG_get_clock();
42 }
43
44
45 static void task_data_get_clock(struct task_data *t)
46 {
47   double now_computation_amount = MSG_task_get_remaining_computation(t->task);
48   double now_clock = MSG_get_clock();
49
50   double done = t->prev_computation_amount - now_computation_amount;
51   double duration = now_clock - t->prev_clock;
52
53   XBT_INFO("%s: %f fops/s", MSG_task_get_name(t->task), done / duration);
54
55   t->prev_computation_amount = now_computation_amount;
56   t->prev_clock = now_clock;
57 }
58
59
60 static void test_pm_pin(void)
61 {
62   xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
63   msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
64   msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
65   msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
66
67
68   struct task_data t1;
69   struct task_data t2;
70   struct task_data t3;
71   struct task_data t4;
72
73   t1.task = MSG_task_create("Task1", 1e16, 0, NULL);
74   t2.task = MSG_task_create("Task2", 1e16, 0, NULL);
75   t3.task = MSG_task_create("Task3", 1e16, 0, NULL);
76   t4.task = MSG_task_create("Task4", 1e16, 0, NULL);
77
78   MSG_process_create("worker1", worker_main, t1.task, pm1);
79   MSG_process_create("worker2", worker_main, t2.task, pm1);
80   MSG_process_create("worker3", worker_main, t3.task, pm1);
81   MSG_process_create("worker4", worker_main, t4.task, pm1);
82
83
84   XBT_INFO("## 1. start 4 tasks on PM1 (2 cores)");
85   task_data_init_clock(&t1);
86   task_data_init_clock(&t2);
87   task_data_init_clock(&t3);
88   task_data_init_clock(&t4);
89
90   MSG_process_sleep(10);
91   task_data_get_clock(&t1);
92   task_data_get_clock(&t2);
93   task_data_get_clock(&t3);
94   task_data_get_clock(&t4);
95
96
97   XBT_INFO("## 2. pin all tasks to CPU0");
98   MSG_task_set_affinity(t1.task, pm1, 0x01);
99   MSG_task_set_affinity(t2.task, pm1, 0x01);
100   MSG_task_set_affinity(t3.task, pm1, 0x01);
101   MSG_task_set_affinity(t4.task, pm1, 0x01);
102
103   MSG_process_sleep(10);
104   task_data_get_clock(&t1);
105   task_data_get_clock(&t2);
106   task_data_get_clock(&t3);
107   task_data_get_clock(&t4);
108
109
110   XBT_INFO("## 3. clear the affinity of task4");
111   MSG_task_set_affinity(t4.task, pm1, 0);
112
113   MSG_process_sleep(10);
114   task_data_get_clock(&t1);
115   task_data_get_clock(&t2);
116   task_data_get_clock(&t3);
117   task_data_get_clock(&t4);
118
119
120   XBT_INFO("## 4. clear the affinity of task3");
121   MSG_task_set_affinity(t3.task, pm1, 0);
122
123   MSG_process_sleep(10);
124   task_data_get_clock(&t1);
125   task_data_get_clock(&t2);
126   task_data_get_clock(&t3);
127   task_data_get_clock(&t4);
128
129
130   XBT_INFO("## 5. clear the affinity of task2");
131   MSG_task_set_affinity(t2.task, pm1, 0);
132
133   MSG_process_sleep(10);
134   task_data_get_clock(&t1);
135   task_data_get_clock(&t2);
136   task_data_get_clock(&t3);
137   task_data_get_clock(&t4);
138
139
140   XBT_INFO("## 6. pin all tasks to CPU0 of another PM (no effect now)");
141   MSG_task_set_affinity(t1.task, pm0, 0);
142   MSG_task_set_affinity(t2.task, pm0, 0);
143   MSG_task_set_affinity(t3.task, pm2, 0);
144   MSG_task_set_affinity(t4.task, pm2, 0);
145
146   MSG_process_sleep(10);
147   task_data_get_clock(&t1);
148   task_data_get_clock(&t2);
149   task_data_get_clock(&t3);
150   task_data_get_clock(&t4);
151
152
153
154   MSG_task_cancel(t1.task);
155   MSG_task_cancel(t2.task);
156   MSG_task_cancel(t3.task);
157   MSG_task_cancel(t4.task);
158   MSG_process_sleep(10);
159   MSG_task_destroy(t1.task);
160   MSG_task_destroy(t2.task);
161   MSG_task_destroy(t3.task);
162   MSG_task_destroy(t4.task);
163 }
164
165
166 static void test_vm_pin(void)
167 {
168   xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
169   msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t); // 1 cores
170   msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t); // 2 cores
171   msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t); // 4 cores
172
173
174   /* set up VMs on PM2 (4 cores) */
175   msg_vm_t vm0 = MSG_vm_create_core(pm2, "VM0");
176   msg_vm_t vm1 = MSG_vm_create_core(pm2, "VM1");
177   msg_vm_t vm2 = MSG_vm_create_core(pm2, "VM2");
178   msg_vm_t vm3 = MSG_vm_create_core(pm2, "VM3");
179
180   s_ws_params_t params;
181   memset(&params, 0, sizeof(params));
182   params.ramsize = 1L * 1024 * 1024;
183   params.skip_stage1 = 1;
184   params.skip_stage2 = 1;
185   //params.mig_speed = 1L * 1024 * 1024;
186   MSG_host_set_params(vm0, &params);
187   MSG_host_set_params(vm1, &params);
188   MSG_host_set_params(vm2, &params);
189   MSG_host_set_params(vm3, &params);
190
191   MSG_vm_start(vm0);
192   MSG_vm_start(vm1);
193   MSG_vm_start(vm2);
194   MSG_vm_start(vm3);
195
196
197   /* set up tasks and processes */
198   struct task_data t0;
199   struct task_data t1;
200   struct task_data t2;
201   struct task_data t3;
202
203   t0.task = MSG_task_create("Task0", 1e16, 0, NULL);
204   t1.task = MSG_task_create("Task1", 1e16, 0, NULL);
205   t2.task = MSG_task_create("Task2", 1e16, 0, NULL);
206   t3.task = MSG_task_create("Task3", 1e16, 0, NULL);
207
208   MSG_process_create("worker0", worker_main, t0.task, vm0);
209   MSG_process_create("worker1", worker_main, t1.task, vm1);
210   MSG_process_create("worker2", worker_main, t2.task, vm2);
211   MSG_process_create("worker3", worker_main, t3.task, vm3);
212
213
214   /* start experiments */
215   XBT_INFO("## 1. start 4 VMs on PM2 (4 cores)");
216   task_data_init_clock(&t0);
217   task_data_init_clock(&t1);
218   task_data_init_clock(&t2);
219   task_data_init_clock(&t3);
220
221   MSG_process_sleep(10);
222   task_data_get_clock(&t0);
223   task_data_get_clock(&t1);
224   task_data_get_clock(&t2);
225   task_data_get_clock(&t3);
226
227
228   XBT_INFO("## 2. pin all VMs to CPU0 of PM2");
229   MSG_vm_set_affinity(vm0, pm2, 0x01);
230   MSG_vm_set_affinity(vm1, pm2, 0x01);
231   MSG_vm_set_affinity(vm2, pm2, 0x01);
232   MSG_vm_set_affinity(vm3, pm2, 0x01);
233
234   MSG_process_sleep(10);
235   task_data_get_clock(&t0);
236   task_data_get_clock(&t1);
237   task_data_get_clock(&t2);
238   task_data_get_clock(&t3);
239
240
241   XBT_INFO("## 3. pin all VMs to CPU0 of PM1 (no effect at now)");
242   /* Because VMs are on PM2, the below operations do not effect computation now. */
243   MSG_vm_set_affinity(vm0, pm1, 0x01);
244   MSG_vm_set_affinity(vm1, pm1, 0x01);
245   MSG_vm_set_affinity(vm2, pm1, 0x01);
246   MSG_vm_set_affinity(vm3, pm1, 0x01);
247
248   MSG_process_sleep(10);
249   task_data_get_clock(&t0);
250   task_data_get_clock(&t1);
251   task_data_get_clock(&t2);
252   task_data_get_clock(&t3);
253
254
255   XBT_INFO("## 4. unpin VM0, and pin VM2 and VM3 to CPU1 of PM2");
256   MSG_vm_set_affinity(vm0, pm2, 0x00);
257   MSG_vm_set_affinity(vm2, pm2, 0x02);
258   MSG_vm_set_affinity(vm3, pm2, 0x02);
259
260   MSG_process_sleep(10);
261   task_data_get_clock(&t0);
262   task_data_get_clock(&t1);
263   task_data_get_clock(&t2);
264   task_data_get_clock(&t3);
265
266
267   XBT_INFO("## 5. migrate all VMs to PM0 (only 1 CPU core)");
268   MSG_vm_migrate(vm0, pm0);
269   MSG_vm_migrate(vm1, pm0);
270   MSG_vm_migrate(vm2, pm0);
271   MSG_vm_migrate(vm3, pm0);
272
273   MSG_process_sleep(10);
274   task_data_get_clock(&t0);
275   task_data_get_clock(&t1);
276   task_data_get_clock(&t2);
277   task_data_get_clock(&t3);
278
279   MSG_process_sleep(10);
280   task_data_get_clock(&t0);
281   task_data_get_clock(&t1);
282   task_data_get_clock(&t2);
283   task_data_get_clock(&t3);
284
285
286   XBT_INFO("## 6. migrate all VMs to PM1 (2 CPU cores, with affinity settings)");
287   MSG_vm_migrate(vm0, pm1);
288   MSG_vm_migrate(vm1, pm1);
289   MSG_vm_migrate(vm2, pm1);
290   MSG_vm_migrate(vm3, pm1);
291
292   MSG_process_sleep(10);
293   task_data_get_clock(&t0);
294   task_data_get_clock(&t1);
295   task_data_get_clock(&t2);
296   task_data_get_clock(&t3);
297
298   MSG_process_sleep(10);
299   task_data_get_clock(&t0);
300   task_data_get_clock(&t1);
301   task_data_get_clock(&t2);
302   task_data_get_clock(&t3);
303
304
305   XBT_INFO("## 7. clear affinity settings on PM1");
306   MSG_vm_set_affinity(vm0, pm1, 0);
307   MSG_vm_set_affinity(vm1, pm1, 0);
308   MSG_vm_set_affinity(vm2, pm1, 0);
309   MSG_vm_set_affinity(vm3, pm1, 0);
310
311   MSG_process_sleep(10);
312   task_data_get_clock(&t0);
313   task_data_get_clock(&t1);
314   task_data_get_clock(&t2);
315   task_data_get_clock(&t3);
316
317   MSG_process_sleep(10);
318   task_data_get_clock(&t0);
319   task_data_get_clock(&t1);
320   task_data_get_clock(&t2);
321   task_data_get_clock(&t3);
322
323
324   /* clean up everything */
325   MSG_task_cancel(t0.task);
326   MSG_task_cancel(t1.task);
327   MSG_task_cancel(t2.task);
328   MSG_task_cancel(t3.task);
329   MSG_process_sleep(10);
330   MSG_task_destroy(t0.task);
331   MSG_task_destroy(t1.task);
332   MSG_task_destroy(t2.task);
333   MSG_task_destroy(t3.task);
334
335   MSG_vm_destroy(vm0);
336   MSG_vm_destroy(vm1);
337   MSG_vm_destroy(vm2);
338   MSG_vm_destroy(vm3);
339 }
340
341
342 static int master_main(int argc, char *argv[])
343 {
344   XBT_INFO("=== Test PM (set affinity) ===");
345   test_pm_pin();
346
347   XBT_INFO("=== Test VM (set affinity) ===");
348   test_vm_pin();
349
350   return 0;
351 }
352
353
354 int main(int argc, char *argv[])
355 {
356   /* Get the arguments */
357   MSG_init(&argc, argv);
358
359   /* load the platform file */
360   if (argc != 2) {
361     printf("Usage: %s examples/msg/cloud/multicore_plat.xml\n", argv[0]);
362     return 1;
363   }
364
365   MSG_create_environment(argv[1]);
366
367   xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
368   msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
369   msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
370   msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
371
372
373   XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm0), MSG_host_get_core_number(pm0), MSG_get_host_speed(pm0));
374   XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm1), MSG_host_get_core_number(pm1), MSG_get_host_speed(pm1));
375   XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm2), MSG_host_get_core_number(pm2), MSG_get_host_speed(pm2));
376
377
378
379   MSG_process_create("master", master_main, NULL, pm0);
380
381
382
383
384   int res = MSG_main();
385   XBT_INFO("Bye (simulation time %g)", MSG_get_clock());
386
387
388   return !(res == MSG_OK);
389 }