Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Performance boost by using a swag internally in SD_simulate
authorMartin Quinson <martin.quinson@loria.fr>
Thu, 20 Oct 2011 08:11:44 +0000 (10:11 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Thu, 20 Oct 2011 08:11:44 +0000 (10:11 +0200)
ChangeLog
src/simdag/private.h
src/simdag/sd_global.c
src/simdag/sd_task.c

index 95f06ca..bc77f6c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,11 @@ SimGrid (3.7) NOT RELEASED; urgency=low
   * Use the partial invalidation optimization by default for the
     network too. Should produce the exact same results, only faster.
 
+  SimDag:
+  * Performance boost by using a swag internally to compute the set of
+    tasks that are finished and should constitute the return value of
+    SD_simulate.
+
   -- $date Da SimGrid team <simgrid-devel@lists.gforge.inria.fr>
 
 SimGrid (3.6.2) stable; urgency=low 
index fc7026a..6939eca 100644 (file)
@@ -13,6 +13,7 @@
 #include "simdag/simdag.h"
 #include "simdag/datatypes.h"
 #include "surf/surf.h"
+#include "xbt/swag.h"
 #include <stdbool.h>
 
 #define SD_INITIALISED() (sd_global != NULL)
@@ -40,6 +41,7 @@ typedef struct SD_global {
   xbt_swag_t done_task_set;
   xbt_swag_t failed_task_set;
 
+  xbt_swag_t return_set;
   int task_number;
 
 } s_SD_global_t, *SD_global_t;
@@ -66,6 +68,7 @@ typedef struct SD_workstation {
 /* Task */
 typedef struct SD_task {
   s_xbt_swag_hookup_t state_hookup;
+  s_xbt_swag_hookup_t return_hookup;
   xbt_swag_t state_set;
   e_SD_task_state_t state;
   void *data;                   /* user data */
@@ -110,6 +113,8 @@ typedef struct SD_dependency {
 } s_SD_dependency_t, *SD_dependency_t;
 
 /* SimDag private functions */
+XBT_PUBLIC(xbt_swag_t) SD_simulate_swag(double how_long); /* could be public, but you need to see the internals of the SD_task_t to use it */
+
 
 SD_link_t __SD_link_create(void *surf_link, void *data);
 void __SD_link_destroy(void *link);
index 762d002..12682cc 100644 (file)
@@ -82,6 +82,8 @@ void SD_init(int *argc, char **argv)
       xbt_swag_new(xbt_swag_offset(task, state_hookup));
   sd_global->failed_task_set =
       xbt_swag_new(xbt_swag_offset(task, state_hookup));
+  sd_global->return_set =
+      xbt_swag_new(xbt_swag_offset(task, return_hookup));
   sd_global->task_number = 0;
 
   surf_init(argc, argv);
@@ -228,34 +230,46 @@ void SD_create_environment(const char *platform_file)
  * \return a NULL-terminated array of \ref SD_task_t whose state has changed.
  * \see SD_task_schedule(), SD_task_watch()
  */
-xbt_dynar_t SD_simulate(double how_long)
-{
+
+xbt_dynar_t SD_simulate(double how_long) {
+  xbt_dynar_t changed_tasks = xbt_dynar_new(sizeof(SD_task_t), NULL);
+  SD_task_t task;
+
+  SD_simulate_swag(how_long);
+  while( (task = xbt_swag_extract(sd_global->return_set)) != NULL) {
+    xbt_dynar_push(changed_tasks, &task);
+  }
+
+  return changed_tasks;
+}
+
+xbt_swag_t SD_simulate_swag(double how_long) {
   double total_time = 0.0;      /* we stop the simulation when total_time >= how_long */
   double elapsed_time = 0.0;
   SD_task_t task, task_safe, dst;
   SD_dependency_t dependency;
   surf_action_t action;
-  xbt_dynar_t changed_tasks = xbt_dynar_new(sizeof(SD_task_t), NULL);
   unsigned int iter, depcnt;
   static int first_time = 1;
 
   SD_CHECK_INIT_DONE();
 
    if (first_time) {
-    XBT_VERB("Starting simulation...");
+     XBT_VERB("Starting simulation...");
 
-    surf_presolve();            /* Takes traces into account */
-    first_time = 0;
-  }
+     surf_presolve();            /* Takes traces into account */
+     first_time = 0;
+   }
 
   sd_global->watch_point_reached = 0;
 
+  while(xbt_swag_extract(sd_global->return_set)) {}
+
   /* explore the runnable tasks */
-  xbt_swag_foreach_safe(task, task_safe, sd_global->runnable_task_set) {
+  xbt_swag_foreach(task, sd_global->runnable_task_set) {
     XBT_VERB("Executing task '%s'", SD_task_get_name(task));
-    if (__SD_task_try_to_run(task)
-        && !xbt_dynar_member(changed_tasks, &task))
-      xbt_dynar_push(changed_tasks, &task);
+    if (__SD_task_try_to_run(task))
+      xbt_swag_insert(task,sd_global->return_set);
   }
 
   /* main loop */
@@ -289,8 +303,7 @@ xbt_dynar_t SD_simulate(double how_long)
                SD_task_get_name(task));
 
         /* the state has changed */
-        if (!xbt_dynar_member(changed_tasks, &task))
-          xbt_dynar_push(changed_tasks, &task);
+        xbt_swag_insert(task,sd_global->return_set);
 
         /* remove the dependencies after this task */
         xbt_dynar_foreach(task->tasks_after, depcnt, dependency) {
@@ -326,9 +339,8 @@ xbt_dynar_t SD_simulate(double how_long)
           if (__SD_task_is_runnable(dst)
               && !sd_global->watch_point_reached) {
             XBT_VERB("Executing task '%s'", SD_task_get_name(dst));
-            if (__SD_task_try_to_run(dst) &&
-                !xbt_dynar_member(changed_tasks, &task))
-              xbt_dynar_push(changed_tasks, &task);
+            if (__SD_task_try_to_run(dst))
+              xbt_swag_insert(dst,sd_global->return_set);
           }
         }
       }
@@ -345,8 +357,7 @@ xbt_dynar_t SD_simulate(double how_long)
         surf_workstation_model->action_unref(action);
         task->surf_action = NULL;
 
-        if (!xbt_dynar_member(changed_tasks, &task))
-          xbt_dynar_push(changed_tasks, &task);
+        xbt_swag_insert(task,sd_global->return_set);
       }
     }
   }
@@ -370,7 +381,7 @@ xbt_dynar_t SD_simulate(double how_long)
          elapsed_time, total_time, sd_global->watch_point_reached);
   XBT_DEBUG("current time = %f", surf_get_clock());
 
-  return changed_tasks;
+  return sd_global->return_set;
 }
 
 /**
index 9735f36..57e34a8 100644 (file)
@@ -41,6 +41,9 @@ SD_task_t SD_task_create(const char *name, void *data, double amount)
   task->state_hookup.next = NULL;
   task->state_set = sd_global->not_scheduled_task_set;
   task->state = SD_NOT_SCHEDULED;
+  task->return_hookup.prev = NULL;
+  task->return_hookup.next = NULL;
+
   task->marked = 0;
   xbt_swag_insert(task, task->state_set);
 
@@ -1253,6 +1256,7 @@ void SD_task_destroy(SD_task_t task)
   if (__SD_task_is_scheduled_or_runnable(task))
     __SD_task_destroy_scheduling_data(task);
   xbt_swag_remove(task, task->state_set);
+  xbt_swag_remove(task, sd_global->return_set);
 
   if (task->name != NULL)
     xbt_free(task->name);
@@ -1364,7 +1368,7 @@ void SD_task_schedulev(SD_task_t task, int count,
   switch (task->kind) {
   case SD_TASK_COMM_E2E:
   case SD_TASK_COMP_SEQ:
-    xbt_assert(task->workstation_nb == count);
+    xbt_assert(task->workstation_nb == count,"Got %d locations, but were expecting %d locations",count,task->workstation_nb);
     for (i = 0; i < count; i++)
       task->workstation_list[i] = list[i];
     SD_task_do_schedule(task);