Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into xbt_random
authorYann Duplouy <yann.duplouy@inria.fr>
Wed, 23 Oct 2019 08:38:03 +0000 (10:38 +0200)
committerYann Duplouy <yann.duplouy@inria.fr>
Wed, 23 Oct 2019 08:38:03 +0000 (10:38 +0200)
examples/s4u/app-bittorrent/s4u-bittorrent.cpp
examples/s4u/app-bittorrent/s4u-bittorrent.hpp
examples/s4u/app-bittorrent/s4u-peer.cpp
examples/s4u/app-bittorrent/s4u-tracker.cpp
examples/s4u/dht-chord/s4u-dht-chord-node.cpp
examples/s4u/dht-chord/s4u-dht-chord.cpp
examples/s4u/dht-chord/s4u-dht-chord.hpp
include/xbt/random.hpp [new file with mode: 0644]
src/xbt/random.cpp [new file with mode: 0644]
tools/cmake/DefinePackages.cmake

index 899802c..47ecad6 100644 (file)
@@ -8,8 +8,6 @@
 #include "s4u-peer.hpp"
 #include "s4u-tracker.hpp"
 
-std::default_random_engine generator;
-
 int main(int argc, char* argv[])
 {
   simgrid::s4u::Engine e(&argc, argv);
index 06fabfa..126017a 100644 (file)
@@ -7,8 +7,8 @@
 #ifndef BITTORRENT_BITTORRENT_HPP_
 #define BITTORRENT_BITTORRENT_HPP_
 
-#include <random>
 #include <simgrid/s4u.hpp>
+#include <xbt/random.hpp>
 
 constexpr char TRACKER_MAILBOX[] = "tracker_mailbox";
 /** Max number of peers sent by the tracker to clients */
@@ -77,6 +77,4 @@ public:
       : type(type), peer_id(peer_id), return_mailbox(return_mailbox), piece(piece){};
 };
 
-extern std::default_random_engine generator;
-
 #endif /* BITTORRENT_BITTORRENT_HPP_ */
index 360bb20..e335d11 100644 (file)
@@ -454,8 +454,7 @@ int Peer::selectPieceToDownload(Connection* remote_peer)
 
     xbt_assert(nb_interesting_pieces != 0);
     // get a random interesting piece
-    std::uniform_int_distribution<int> dist(0, nb_interesting_pieces - 1);
-    int random_piece_index = dist(generator);
+    int random_piece_index = simgrid::xbt::random::uniform_int(0, nb_interesting_pieces - 1);
     int current_index      = 0;
     for (unsigned int i = 0; i < FILE_PIECES; i++) {
       if (hasNotPiece(i) && remote_peer->hasPiece(i)) {
@@ -478,8 +477,7 @@ int Peer::selectPieceToDownload(Connection* remote_peer)
         nb_interesting_pieces++;
     xbt_assert(nb_interesting_pieces != 0);
     // get a random interesting piece
-    std::uniform_int_distribution<int> dist(0, nb_interesting_pieces - 1);
-    int random_piece_index = dist(generator);
+    int random_piece_index = simgrid::xbt::random::uniform_int(0, nb_interesting_pieces - 1);
     int current_index      = 0;
     for (unsigned int i = 0; i < FILE_PIECES; i++) {
       if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) {
@@ -512,8 +510,7 @@ int Peer::selectPieceToDownload(Connection* remote_peer)
     // get a random rarest piece
     int random_rarest_index = 0;
     if (nb_min_pieces > 0) {
-      std::uniform_int_distribution<int> dist(0, nb_min_pieces - 1);
-      random_rarest_index = dist(generator);
+      random_rarest_index = simgrid::xbt::random::uniform_int(0, nb_min_pieces - 1);
     }
     for (unsigned int i = 0; i < FILE_PIECES; i++)
       if (pieces_count[i] == min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) {
@@ -563,8 +560,7 @@ void Peer::updateChokedPeers()
       do {
         // We choose a random peer to unchoke.
         std::unordered_map<int, Connection>::iterator chosen_peer_it = connected_peers.begin();
-        std::uniform_int_distribution<int> dist(0, connected_peers.size() - 1);
-        std::advance(chosen_peer_it, dist(generator));
+        std::advance(chosen_peer_it, simgrid::xbt::random::uniform_int(0, connected_peers.size() - 1));
         chosen_peer = &chosen_peer_it->second;
         if (not chosen_peer->interested || not chosen_peer->choked_upload)
           chosen_peer = nullptr;
index 390020a..c4bfc16 100644 (file)
@@ -52,8 +52,7 @@ void Tracker::operator()()
       while (tried < max_tries) {
         do {
           next_peer = known_peers.begin();
-          std::uniform_int_distribution<int> dist(0, nb_known_peers - 1);
-          std::advance(next_peer, dist(generator));
+          std::advance(next_peer, simgrid::xbt::random::uniform_int(0, nb_known_peers - 1));
         } while (ta->getPeers().find(*next_peer) != ta->getPeers().end());
         ta->addPeer(*next_peer);
         tried++;
index 1fa0c39..f76484c 100644 (file)
@@ -134,7 +134,7 @@ void Node::notifyAndQuit()
 void Node::randomLookup()
 {
   int res          = id_;
-  int random_index = generator() % nb_bits;
+  int random_index = simgrid::xbt::random::uniform_int(0, nb_bits - 1);
   int random_id    = fingers_[random_index];
   XBT_DEBUG("Making a lookup request for id %d", random_id);
   if (random_id != id_)
index b8d20a7..372c509 100644 (file)
@@ -11,8 +11,6 @@ int nb_bits  = 24;
 int nb_keys  = 0;
 int timeout  = 50;
 
-std::mt19937 generator;
-
 int main(int argc, char* argv[])
 {
   simgrid::s4u::Engine e(&argc, argv);
index 81821cf..eea1f2f 100644 (file)
@@ -6,8 +6,8 @@
 #ifndef S4U_CHORD_HPP
 #define S4U_CHORD_HPP
 #include "simgrid/s4u.hpp"
-#include <random>
 #include <string>
+#include <xbt/random.hpp>
 #include <xbt/str.h>
 
 constexpr double MAX_SIMULATION_TIME              = 1000;
@@ -21,8 +21,6 @@ extern int nb_bits;
 extern int nb_keys;
 extern int timeout;
 
-extern std::mt19937 generator;
-
 /* Types of tasks exchanged between nodes. */
 enum e_message_type_t {
   FIND_SUCCESSOR,
diff --git a/include/xbt/random.hpp b/include/xbt/random.hpp
new file mode 100644 (file)
index 0000000..cf2b168
--- /dev/null
@@ -0,0 +1,22 @@
+/* Copyright (c) 2019. The SimGrid Team. All rights reserved.               */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SIMGRID_XBT_RANDOM_HPP
+#define SIMGRID_XBT_RANDOM_HPP
+
+#include <random>
+
+namespace simgrid {
+namespace xbt {
+namespace random {
+int uniform_int(int, int);
+double uniform_real(double, double);
+double exponential(double);
+double normal(double, double);
+} // namespace random
+} // namespace xbt
+} // namespace simgrid
+
+#endif
diff --git a/src/xbt/random.cpp b/src/xbt/random.cpp
new file mode 100644 (file)
index 0000000..03c544a
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (c) 2019. The SimGrid Team. All rights reserved.               */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "xbt/random.hpp"
+#include "xbt/asserts.h"
+#include <limits>
+#include <random>
+
+namespace simgrid {
+namespace xbt {
+namespace random {
+std::mt19937 mt19937_gen;
+
+int uniform_int(int min, int max)
+{
+  unsigned long gmin   = mt19937_gen.min();
+  unsigned long gmax   = mt19937_gen.max();
+  unsigned long grange = gmax - gmin + 1;
+  unsigned long range  = max - min + 1;
+  xbt_assert(range < grange || range == grange, "The current implementation of the uniform integer distribution does "
+                                                "not allow range to be higher than mt19937's range");
+  unsigned long mult       = grange / range;
+  unsigned long maxallowed = gmin + (mult + 1) * range - 1;
+  while (true) {
+    unsigned long value = mt19937_gen();
+    if (value > maxallowed) {
+    } else {
+      return value % range + min;
+    }
+  }
+}
+
+double uniform_real(double min, double max)
+{
+  // This reuses Boost's uniform real distribution ideas
+  unsigned long numerator = mt19937_gen() - mt19937_gen.min();
+  unsigned long divisor   = mt19937_gen.max() - mt19937_gen.min();
+  return min + (max - min) * numerator / divisor;
+}
+
+double exponential(double lambda)
+{
+  unsigned long numerator = mt19937_gen() - mt19937_gen.min();
+  unsigned long divisor   = mt19937_gen.max() - mt19937_gen.min();
+  return -1 / lambda * log(numerator / divisor);
+}
+
+double normal(double mean, double sd)
+{
+  unsigned long numeratorA = mt19937_gen() - mt19937_gen.min();
+  unsigned long numeratorB = mt19937_gen() - mt19937_gen.min();
+  unsigned long divisor    = mt19937_gen.max() - mt19937_gen.min();
+  double u1                = numeratorA / divisor;
+  while (u1 < std::numeric_limits<double>::min()) {
+    numeratorA = mt19937_gen() - mt19937_gen.min();
+    u1         = numeratorA / divisor;
+  }
+  double z0 = sqrt(-2.0 * log(numeratorA / divisor)) * cos(2 * M_PI * numeratorB / divisor);
+  return z0 * sd + mean;
+}
+
+} // namespace random
+} // namespace xbt
+} // namespace simgrid
index c50a3de..d084dd1 100644 (file)
@@ -283,6 +283,7 @@ set(XBT_SRC
   src/xbt/memory_map.hpp
   src/xbt/OsSemaphore.hpp
   src/xbt/parmap.cpp
+  src/xbt/random.cpp
   src/xbt/snprintf.c
   src/xbt/string.cpp
   src/xbt/xbt_log_appender_file.cpp
@@ -774,6 +775,7 @@ set(headers_to_install
   include/xbt/module.h
   include/xbt/parmap.h
   include/xbt/range.hpp
+  include/xbt/random.hpp
   include/xbt/replay.hpp
   include/xbt/signal.hpp
   include/xbt/str.h