Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
authorMartin Quinson <martin.quinson@loria.fr>
Mon, 10 Sep 2018 12:39:55 +0000 (14:39 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Mon, 10 Sep 2018 12:41:29 +0000 (14:41 +0200)
doc/doxygen/options.doc
docs/source/app_s4u.rst
examples/s4u/async-waitall/s4u-async-waitall.cpp
src/kernel/context/ContextThread.hpp
src/smpi/internals/smpi_bench.cpp
src/smpi/internals/smpi_global.cpp

index 209de0b..200b091 100644 (file)
@@ -1248,28 +1248,33 @@ at least one huge page:
 Then, you can pass the option --cfg=smpi/shared-malloc-hugepage:/home/huge
 to smpirun to actually activate the huge page support in shared mallocs.
 
-@subsection options_model_smpi_wtime smpi/wtime: Inject constant times for calls to MPI_Wtime
+@subsection options_model_smpi_wtime smpi/wtime: Inject constant times for calls to MPI_Wtime, gettimeofday and clock_gettime
 
-@b Default value: 0
-
-By setting this option, you can control the amount of time a process sleeps
-when MPI_Wtime() is called; this is important, because SimGrid normally only
-advances the time while communication is happening and thus,
-MPI_Wtime will not add to the time, resulting in a deadlock if used as a
-break-condition.
+@b Default value: 1ms
 
-Here is an example:
+This option controls the amount of (simulated) time spent in calls to
+MPI_Wtime(), gettimeofday() and clock_gettime(). If you set this value
+to 0, the simulated clock is not advanced in these calls, which leads
+to issue if your application contains such a loop:
 
 @code{.unparsed}
     while(MPI_Wtime() < some_time_bound) {
-        ...
+        /* some tests, with no communication nor computation */
     }
 @endcode
 
-If the time is never advanced, this loop will clearly never end as MPI_Wtime()
-always returns the same value. Hence, pass a (small) value to the smpi/wtime
-option to force a call to MPI_Wtime to advance the time as well.
-
+When the option smpi/wtime is set to 0, the time advances only on
+communications and computations, so the previous code results in an
+infinite loop: the current [simulated] time will never reach @c
+some_time_bound.  This infinite loop is avoided when that option is
+set to a small amount, as it is by default since SimGrid v3.21.
+
+Note that if your application does not contain any loop depending on
+the current time only, then setting this option to a non-zero value
+will slow down your simulations by a tiny bit: the simulation loop has
+to be broken and reset each time your code ask for the current time.
+If the simulation speed really matters to you, you can avoid this
+extra delay by setting smpi/wtime to 0.
 
 @section options_generic Configuring other aspects of SimGrid
 
index f386d13..a4a661a 100644 (file)
@@ -41,8 +41,8 @@ completion of these activities.
 When **communicating**, data is not directly sent to other actors but
 posted onto a |Mailbox|_ that serve as rendez-vous point between
 communicating actors. This means that you don't need to know who you
-are talking to, you just put your communication `Send` request in a
-mailbox, and it will be matched with a complementary `Receive`
+are talking to, you just put your communication `Put` request in a
+mailbox, and it will be matched with a complementary `Get`
 request.  Alternatively, actors can interact through **classical
 synchronization mechanisms** such as |Barrier|_, |Semaphore|_,
 |Mutex|_ and |ConditionVariable|_.
@@ -197,8 +197,8 @@ with
      
 .. literalinclude:: ../../examples/s4u/async-waitall/s4u-async-waitall.cpp
    :language: c++
-   :start-after: send-begin
-   :end-before: send-end
+   :start-after: put-begin
+   :end-before: put-end
    :dedent: 4
 
 
index 7c7c908..f49f7bf 100644 (file)
@@ -58,7 +58,7 @@ public:
       pending_comms.push_back(comm);
     }
 
-    /* Start sending messages to let the workers know that they should stop */ // sphinx-doc: send-begin
+    /* Start sending messages to let the workers know that they should stop */ // sphinx-doc: put-begin
     for (int i = 0; i < receivers_count; i++) {
       XBT_INFO("Send 'finalize' to 'receiver-%d'", i);
       simgrid::s4u::CommPtr comm = mboxes[i]->put_async(new std::string("finalize"), 0);
@@ -68,7 +68,7 @@ public:
 
     /* Now that all message exchanges were initiated, wait for their completion in one single call */
     simgrid::s4u::Comm::wait_all(&pending_comms);
-    // sphinx-doc: send-end
+    // sphinx-doc: put-end
 
     XBT_INFO("Goodbye now!");
   }
index 48a9d1a..cd83102 100644 (file)
@@ -16,7 +16,7 @@ namespace simgrid {
 namespace kernel {
 namespace context {
 
-class ThreadContext : public AttachContext {
+class XBT_PUBLIC ThreadContext : public AttachContext {
 public:
   ThreadContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process, bool maestro);
   ~ThreadContext() override;
@@ -46,7 +46,7 @@ private:
   static void* wrapper(void *param);
 };
 
-class SerialThreadContext : public ThreadContext {
+class XBT_PUBLIC SerialThreadContext : public ThreadContext {
 public:
   SerialThreadContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process, bool maestro)
       : ThreadContext(std::move(code), cleanup_func, process, maestro)
index 96996c0..3ebf408 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi, "Logging specific to SMPI (benchmarking)");
 
+static simgrid::config::Flag<double>
+    smpi_wtime_sleep("smpi/wtime",
+                     "Minimum time to inject inside a call to MPI_Wtime(), gettimeofday() and clock_gettime()",
+                     1e-6 /* Documented to be 1ms */);
+
 double smpi_cpu_threshold = -1;
 double smpi_host_speed;
 
@@ -35,7 +40,6 @@ SharedMallocType smpi_cfg_shared_malloc = SharedMallocType::GLOBAL;
 double smpi_total_benched_time = 0;
 
 extern "C" XBT_PUBLIC void smpi_execute_flops_(double* flops);
-extern "C" XBT_PUBLIC simgrid::config::Flag<double> smpi_wtime_sleep;
 
 void smpi_execute_flops_(double *flops)
 {
@@ -179,7 +183,7 @@ void smpi_bench_end()
   smpi_total_benched_time += xbt_os_timer_elapsed(timer);
 }
 
-/* Private sleep function used by smpi_sleep() and smpi_usleep() */
+/* Private sleep function used by smpi_sleep(), smpi_usleep() and friends */
 static unsigned int private_sleep(double secs)
 {
   smpi_bench_end();
@@ -234,7 +238,7 @@ int smpi_gettimeofday(struct timeval* tv, struct timezone* tz)
     tv->tv_usec = static_cast<suseconds_t>((now - tv->tv_sec) * 1e6);
 #endif
   }
-  if(smpi_wtime_sleep > 0)
+  if (smpi_wtime_sleep > 0)
     simcall_process_sleep(smpi_wtime_sleep);
   smpi_bench_begin();
   return 0;
@@ -252,13 +256,28 @@ int smpi_clock_gettime(clockid_t clk_id, struct timespec* tp)
     tp->tv_sec = static_cast<time_t>(now);
     tp->tv_nsec = static_cast<long int>((now - tp->tv_sec) * 1e9);
   }
-  if(smpi_wtime_sleep > 0)
+  if (smpi_wtime_sleep > 0)
     simcall_process_sleep(smpi_wtime_sleep);
   smpi_bench_begin();
   return 0;
 }
 #endif
 
+double smpi_mpi_wtime()
+{
+  double time;
+  if (smpi_process()->initialized() && not smpi_process()->finalized() && not smpi_process()->sampling()) {
+    smpi_bench_end();
+    time = SIMIX_get_clock();
+    if (smpi_wtime_sleep > 0)
+      simcall_process_sleep(smpi_wtime_sleep);
+    smpi_bench_begin();
+  } else {
+    time = SIMIX_get_clock();
+  }
+  return time;
+}
+
 extern double sg_surf_precision;
 unsigned long long smpi_rastro_resolution ()
 {
index 0c5d88a..aaef32d 100644 (file)
@@ -95,8 +95,6 @@ MPI_Errhandler *MPI_ERRHANDLER_NULL = nullptr;
 // No instance gets manually created; check also the smpirun.in script as
 // this default name is used there as well (when the <actor> tag is generated).
 static const std::string smpi_default_instance_name("smpirun");
-XBT_PRIVATE simgrid::config::Flag<double> smpi_wtime_sleep(
-  "smpi/wtime", "Minimum time to inject inside a call to MPI_Wtime", 0.0);
 static simgrid::config::Flag<double> smpi_init_sleep(
   "smpi/init", "Time to inject inside a call to MPI_Init", 0.0);
 
@@ -745,24 +743,3 @@ void smpi_mpi_init() {
   if(smpi_init_sleep > 0)
     simcall_process_sleep(smpi_init_sleep);
 }
-
-double smpi_mpi_wtime(){
-  double time;
-  if (smpi_process()->initialized() != 0 && smpi_process()->finalized() == 0 && smpi_process()->sampling() == 0) {
-    smpi_bench_end();
-    time = SIMIX_get_clock();
-    // to avoid deadlocks if used as a break condition, such as
-    //     while (MPI_Wtime(...) < time_limit) {
-    //       ....
-    //     }
-    // because the time will not normally advance when only calls to MPI_Wtime
-    // are made -> deadlock (MPI_Wtime never reaches the time limit)
-    if(smpi_wtime_sleep > 0)
-      simcall_process_sleep(smpi_wtime_sleep);
-    smpi_bench_begin();
-  } else {
-    time = SIMIX_get_clock();
-  }
-  return time;
-}
-