Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
argument why parallel execution don't jeopardize reproducibility even if we never...
authorMartin Quinson <martin.quinson@loria.fr>
Mon, 14 May 2012 12:59:07 +0000 (14:59 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Mon, 14 May 2012 12:59:07 +0000 (14:59 +0200)
src/simix/smx_global.c
src/simix/smx_process.c

index 0de13d2..eb2a141 100644 (file)
@@ -197,8 +197,63 @@ void SIMIX_run(void)
     while (!xbt_dynar_is_empty(simix_global->process_to_run)) {
       XBT_DEBUG("New Sub-Schedule Round; size(queue)=%lu",
               xbt_dynar_length(simix_global->process_to_run));
+
+      /* Run all processes that are ready to run, possibly in parallel */
       SIMIX_process_runall();
+
+      /* Move all killing processes to the end of the list, because killing a process that have an ongoing simcall is a bad idea */
       xbt_dynar_three_way_partition(simix_global->process_that_ran, process_syscall_color);
+
+      /* answer sequentially and in a fixed arbitrary order all the simcalls that were issued during that sub-round */
+
+      /* WARNING, the order *must* be fixed or you'll jeopardize the simulation reproducibility (see RR-7653) */
+
+      /* Here, the order is ok because:
+       *   - if there is no kill during the simulation, processes remain sorted according by their PID.
+       *     rational: This can be proved inductively.
+       *        Assume that process_to_run is sorted at a beginning of one round (it is at round 0: the deployment file is parsed linearly).
+       *        Let's show that it is still so at the end of this round.
+       *        - if a process is added when being created, that's from maestro. It can be either at startup
+       *          time (and then in PID order), or in response to a process_create simcall. Since simcalls are handled
+       *          in arbitrary order (inductive hypothesis), we are fine.
+       *        - If a process is added because it's getting killed, its subsequent actions shouldn't matter
+       *        - If a process gets added to process_to_run because one of their blocking action constituting the meat
+       *          of a simcall terminates, we're still good. Proof:
+       *          - You are added from SIMIX_simcall_answer() only. When this function is called depends on the resource
+       *            kind (network, cpu, disk, whatever), but the same arguments hold. Let's take communications as an example.
+       *          - For communications, this function is called from SIMIX_comm_finish().
+       *            This function itself don't mess with the order since simcalls are handled in FIFO order.
+       *            The function is called:
+       *            - before the comm starts (invalid parameters, or resource already dead or whatever).
+       *              The order then trivial holds since maestro didn't interrupt its handling of the simcall yet
+       *            - because the communication failed or were canceled after startup. In this case, it's called from the function
+       *              we are in, by the chunk:
+       *                       set = model->states.failed_action_set;
+       *                       while ((action = xbt_swag_extract(set)))
+       *                          SIMIX_simcall_post((smx_action_t) action->data);
+       *              This order is also fixed because it depends of the order in which the surf actions were
+       *              added to the system, and only maestro can add stuff this way, through simcalls.
+       *              We thus use the inductive hypothesis once again to conclude that the order in which actions are
+       *              poped out of the swag does not depend on the user code's execution order.
+       *            - because the communication terminated. In this case, actions are served in the order given by
+       *                       set = model->states.done_action_set;
+       *                       while ((action = xbt_swag_extract(set)))
+       *                          SIMIX_simcall_post((smx_action_t) action->data);
+       *              and the argument is very similar to the previous one.
+       *            So, in any case, the orders of calls to SIMIX_comm_finish() do not depend on the order in which user processes are executed.
+       *          So, in any cases, the orders of processes within process_to_run do not depend on the order in which user processes were executed previously.
+       *     So, if there is no killing in the simulation, the simulation reproducibility is not jeopardized.
+       *   - If there is some process killings, the order is changed by this decision that comes from user-land
+       *     But this decision may not have been motivated by a situation that were different because the simulation is not reproducible.
+       *     So, even the order change induced by the process killing is perfectly reproducible.
+       *
+       *   So science works, bitches [http://xkcd.com/54/].
+       *
+       *   We could sort the process_that_ran array completely so that we can describe the order in which simcalls are handled
+       *   (like "according to the PID of issuer"), but it's not mandatory (order is fixed already even if unfriendly).
+       *   That would thus be a pure waste of time.
+       */
+
       xbt_dynar_foreach(simix_global->process_that_ran, iter, process) {
         if (process->simcall.call != SIMCALL_NONE) {
           SIMIX_simcall_pre(&process->simcall, 0);
index 409211a..aa1378a 100644 (file)
@@ -169,7 +169,7 @@ smx_process_t SIMIX_process_create_from_wrapper(smx_process_arg_t args) {
  *
  * This function actually creates the process.
  * It may be called when a SIMCALL_PROCESS_CREATE simcall occurs,
- * or directly for SIMIX internal purposes.
+ * or directly for SIMIX internal purposes. The sure thing is that it's called from maestro context.
  *
  * \return the process created
  */