From: Martin Quinson Date: Mon, 10 Sep 2018 12:35:57 +0000 (+0200) Subject: Improve option smpi/wtime X-Git-Tag: v3_21~113 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/9fe49bf54cebc7c586e72cab932a175ed5b41ae7 Improve option smpi/wtime - Set default value to 1ms instead of 0. This default settings may lead to slower simulation, but it works in more situations. - Also apply this delay in gettimeofday() and clock_gettime() - Improve the documentation. --- diff --git a/doc/doxygen/options.doc b/doc/doxygen/options.doc index 209de0b6af..200b0915a1 100644 --- a/doc/doxygen/options.doc +++ b/doc/doxygen/options.doc @@ -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 diff --git a/src/smpi/internals/smpi_bench.cpp b/src/smpi/internals/smpi_bench.cpp index 302050337c..c3d7e18893 100644 --- a/src/smpi/internals/smpi_bench.cpp +++ b/src/smpi/internals/smpi_bench.cpp @@ -28,8 +28,10 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi, "Logging specific to SMPI (benchmarking)"); -static simgrid::config::Flag smpi_wtime_sleep("smpi/wtime", "Minimum time to inject inside a call to MPI_Wtime", - 0.0); +static simgrid::config::Flag + 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; @@ -235,6 +237,8 @@ int smpi_gettimeofday(struct timeval* tv, struct timezone* tz) tv->tv_usec = static_cast((now - tv->tv_sec) * 1e6); #endif } + if (smpi_wtime_sleep > 0) + simcall_process_sleep(smpi_wtime_sleep); smpi_bench_begin(); return 0; } @@ -251,11 +255,28 @@ int smpi_clock_gettime(clockid_t clk_id, struct timespec* tp) tp->tv_sec = static_cast(now); tp->tv_nsec = static_cast((now - tp->tv_sec) * 1e9); } + 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 () { @@ -276,27 +297,6 @@ unsigned long long smpi_rastro_timestamp () return static_cast(sec) * smpi_rastro_resolution() + pre; } -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(); - // 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; -} - /* ****************************** Functions related to the SMPI_SAMPLE_ macros ************************************/ namespace { class SampleLocation : public std::string {