+ now = SIMIX_get_clock();
+ if (tv) {
+ tv->tv_sec = (time_t)now;
+#ifdef WIN32
+ tv->tv_usec = (useconds_t)((now - tv->tv_sec) * 1e6);
+#else
+ tv->tv_usec = (suseconds_t)((now - tv->tv_sec) * 1e6);
+#endif
+ }
+ smpi_bench_begin();
+ return 0;
+}
+
+extern double sg_maxmin_precision;
+unsigned long long smpi_rastro_resolution (void)
+{
+ smpi_bench_end();
+ double resolution = (1/sg_maxmin_precision);
+ smpi_bench_begin();
+ return (unsigned long long)resolution;
+}
+
+unsigned long long smpi_rastro_timestamp (void)
+{
+ smpi_bench_end();
+ double now = SIMIX_get_clock();
+
+ unsigned long long sec = (unsigned long long)now;
+ unsigned long long pre = (now - sec) * smpi_rastro_resolution();
+ smpi_bench_begin();
+ return (unsigned long long)sec * smpi_rastro_resolution() + pre;
+}
+
+/* ****************************** Functions related to the SMPI_SAMPLE_ macros ************************************/
+typedef struct {
+ int iters; /* amount of requested iterations */
+ int count; /* amount of iterations done so far */
+ double threshold; /* maximal stderr requested (if positive) */
+ double relstderr; /* observed stderr so far */
+ double mean; /* mean of benched times, to be used if the block is disabled */
+ double sum; /* sum of benched times (to compute the mean and stderr) */
+ double sum_pow2; /* sum of the square of the benched times (to compute the stderr) */
+ int benching; /* 1: we are benchmarking; 0: we have enough data, no bench anymore */
+} local_data_t;
+
+static char *sample_location(int global, const char *file, int line) {
+ if (global) {
+ return bprintf("%s:%d", file, line);
+ } else {
+ return bprintf("%s:%d:%d", file, line, smpi_process_index());
+ }
+}
+static int sample_enough_benchs(local_data_t *data) {
+ int res = data->count >= data->iters;
+ if (data->threshold>0.0) {
+ if (data->count <2)
+ res = 0; // not enough data
+ if (data->relstderr > data->threshold)
+ res = 0; // stderr too high yet
+ }
+ XBT_DEBUG("%s (count:%d iter:%d stderr:%f thres:%f mean:%fs)",
+ (res?"enough benchs":"need more data"),
+ data->count, data->iters, data->relstderr, data->threshold, data->mean);
+ return res;
+}
+
+void smpi_sample_1(int global, const char *file, int line, int iters, double threshold)
+{
+ char *loc = sample_location(global, file, line);
+ local_data_t *data;
+
+ smpi_bench_end(); /* Take time from previous, unrelated computation into account */
+ if (!samples)
+ samples = xbt_dict_new_homogeneous(free);
+
+ data = xbt_dict_get_or_null(samples, loc);
+ if (!data) {
+ xbt_assert(threshold>0 || iters>0,
+ "You should provide either a positive amount of iterations to bench, or a positive maximal stderr (or both)");
+ data = (local_data_t *) xbt_new(local_data_t, 1);
+ data->count = 0;
+ data->sum = 0.0;
+ data->sum_pow2 = 0.0;
+ data->iters = iters;
+ data->threshold = threshold;
+ data->benching = 1; // If we have no data, we need at least one
+ data->mean = 0;
+ xbt_dict_set(samples, loc, data, NULL);
+ XBT_DEBUG("XXXXX First time ever on benched nest %s.",loc);
+ } else {
+ if (data->iters != iters || data->threshold != threshold) {
+ XBT_ERROR("Asked to bench block %s with different settings %d, %f is not %d, %f. How did you manage to give two numbers at the same line??",
+ loc, data->iters, data->threshold, iters,threshold);
+ THROW_IMPOSSIBLE;