gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r24451 - in gnunet/src: fragmentation include transport


From: gnunet
Subject: [GNUnet-SVN] r24451 - in gnunet/src: fragmentation include transport
Date: Mon, 22 Oct 2012 14:36:41 +0200

Author: grothoff
Date: 2012-10-22 14:36:41 +0200 (Mon, 22 Oct 2012)
New Revision: 24451

Modified:
   gnunet/src/fragmentation/fragmentation.c
   gnunet/src/fragmentation/test_fragmentation.c
   gnunet/src/include/gnunet_fragmentation_lib.h
   gnunet/src/transport/plugin_transport_udp.c
   gnunet/src/transport/plugin_transport_wlan.c
Log:
-trying to fix fragmentation / udp performance, not working yet

Modified: gnunet/src/fragmentation/fragmentation.c
===================================================================
--- gnunet/src/fragmentation/fragmentation.c    2012-10-22 12:34:03 UTC (rev 
24450)
+++ gnunet/src/fragmentation/fragmentation.c    2012-10-22 12:36:41 UTC (rev 
24451)
@@ -52,9 +52,14 @@
   /**
    * Current expected delay for ACKs.
    */
-  struct GNUNET_TIME_Relative delay;
+  struct GNUNET_TIME_Relative ack_delay;
 
   /**
+   * Current expected delay between messages.
+   */
+  struct GNUNET_TIME_Relative msg_delay;
+
+  /**
    * Next allowed transmission time.
    */
   struct GNUNET_TIME_Absolute delay_until;
@@ -181,11 +186,11 @@
     return;
   }
   fc->next_transmission = (fc->next_transmission + 1) % 64;
-  wrap |= (fc->next_transmission == 0);
+  wrap |= (0 == fc->next_transmission);
   while (0 == (fc->acks & (1LL << fc->next_transmission)))
   {
     fc->next_transmission = (fc->next_transmission + 1) % 64;
-    wrap |= (fc->next_transmission == 0);
+    wrap |= (0 == fc->next_transmission);
   }
 
   /* assemble fragmentation message */
@@ -217,16 +222,17 @@
     delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize);
   else
     delay = GNUNET_TIME_UNIT_ZERO;
+  delay = GNUNET_TIME_relative_max (delay,
+                                   fc->msg_delay);
   if (wrap)
   {
     /* full round transmitted wait 2x delay for ACK before going again */
     fc->num_rounds++;
-    delay =
-        GNUNET_TIME_relative_max (GNUNET_TIME_relative_multiply (delay, 2),
-                                  GNUNET_TIME_relative_multiply (fc->delay,
-                                                                 
fc->num_rounds));
+    delay = GNUNET_TIME_relative_multiply (delay, 2);
+    fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay, 
+                                                  2 + (size / (fc->mtu - 
sizeof (struct FragmentHeader))));
     /* never use zero, need some time for ACK always */
-    delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay);
+    delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay);    
     fc->wack = GNUNET_YES;
     fc->last_round = GNUNET_TIME_absolute_get ();
     GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1,
@@ -250,7 +256,9 @@
  * @param stats statistics context
  * @param mtu the maximum message size for each fragment
  * @param tracker bandwidth tracker to use for flow control (can be NULL)
- * @param delay expected delay between fragment transmission
+ * @param msg_delay initial delay to insert between fragment transmissions
+ *              based on previous messages
+ * @param ack_delay expected delay between fragment transmission
  *              and ACK based on previous messages
  * @param msg the message to fragment
  * @param proc function to call for each fragment to transmit
@@ -261,7 +269,8 @@
 GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
                                 uint16_t mtu,
                                 struct GNUNET_BANDWIDTH_Tracker *tracker,
-                                struct GNUNET_TIME_Relative delay,
+                                struct GNUNET_TIME_Relative msg_delay,
+                                struct GNUNET_TIME_Relative ack_delay,
                                 const struct GNUNET_MessageHeader *msg,
                                 GNUNET_FRAGMENT_MessageProcessor proc,
                                 void *proc_cls)
@@ -280,7 +289,8 @@
   fc->stats = stats;
   fc->mtu = mtu;
   fc->tracker = tracker;
-  fc->delay = delay;
+  fc->ack_delay = ack_delay;
+  fc->msg_delay = msg_delay;
   fc->msg = (const struct GNUNET_MessageHeader *) &fc[1];
   fc->proc = proc;
   fc->proc_cls = proc_cls;
@@ -339,7 +349,11 @@
   const struct FragmentAcknowledgement *fa;
   uint64_t abits;
   struct GNUNET_TIME_Relative ndelay;
+  unsigned int ack_cnt;
+  unsigned int snd_cnt;
+  unsigned int i;
 
+  fprintf (stderr, "Got ACK!\n");
   if (sizeof (struct FragmentAcknowledgement) != ntohs (msg->size))
   {
     GNUNET_break_op (0);
@@ -355,9 +369,40 @@
     /* normal ACK, can update running average of delay... */
     fc->wack = GNUNET_NO;
     ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round);
-    fc->delay.rel_value =
-        (ndelay.rel_value / fc->num_transmissions + 3 * fc->delay.rel_value) / 
4;
+    fc->ack_delay.rel_value =
+        (ndelay.rel_value / fc->num_transmissions + 3 * 
fc->ack_delay.rel_value) / 4;    
     fc->num_transmissions = 0;
+    /* calculate ratio msg sent vs. msg acked */
+    ack_cnt = 0;
+    snd_cnt = 0;
+    for (i=0;i<64;i++)
+    {
+      if (1 == (fc->acks_mask & (1 << i)))
+      {
+       snd_cnt++;
+       if (0 == (abits & (1 << i)))
+         ack_cnt++;
+      }
+    }
+    if (0 == ack_cnt)
+    {
+      /* complete loss */
+      fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay, 
+                                                    snd_cnt);      
+    }
+    else if (snd_cnt > ack_cnt)
+    {
+      /* some loss, slow down proportionally */
+      fc->msg_delay.rel_value = ((fc->msg_delay.rel_value * ack_cnt) / 
snd_cnt);
+    }
+    else if (0 < fc->msg_delay.rel_value)
+    {
+      fc->msg_delay.rel_value--; /* try a bit faster */
+    }
+    fc->msg_delay = GNUNET_TIME_relative_max (fc->msg_delay,
+                                             GNUNET_TIME_UNIT_SECONDS);
+    fprintf (stderr, "New msg delay: %llu\n",
+            (unsigned long long )fc->msg_delay.rel_value);
   }
   GNUNET_STATISTICS_update (fc->stats,
                             _("# fragment acknowledgements received"), 1,
@@ -406,19 +451,23 @@
  * resources).
  *
  * @param fc fragmentation context
- * @return average delay between transmission and ACK for the
- *         last message, FOREVER if the message was not fully transmitted
+ * @param msg_delay where to store average delay between individual message 
transmissions the
+ *         last message (OUT only)
+ * @param ack_delay where to store average delay between transmission and ACK 
for the
+ *         last message, set to FOREVER if the message was not fully 
transmitted (OUT only)
  */
-struct GNUNET_TIME_Relative
-GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc)
+void
+GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc,
+                                struct GNUNET_TIME_Relative *msg_delay,
+                                struct GNUNET_TIME_Relative *ack_delay)
 {
-  struct GNUNET_TIME_Relative ret;
-
   if (fc->task != GNUNET_SCHEDULER_NO_TASK)
     GNUNET_SCHEDULER_cancel (fc->task);
-  ret = fc->delay;
+  if (NULL != ack_delay)
+    *ack_delay = fc->ack_delay;
+  if (NULL != msg_delay)
+    *msg_delay = fc->msg_delay;
   GNUNET_free (fc);
-  return ret;
 }
 
 

Modified: gnunet/src/fragmentation/test_fragmentation.c
===================================================================
--- gnunet/src/fragmentation/test_fragmentation.c       2012-10-22 12:34:03 UTC 
(rev 24450)
+++ gnunet/src/fragmentation/test_fragmentation.c       2012-10-22 12:36:41 UTC 
(rev 24451)
@@ -77,7 +77,7 @@
   {
     if (frags[i] == NULL)
       continue;
-    GNUNET_FRAGMENT_context_destroy (frags[i]);
+    GNUNET_FRAGMENT_context_destroy (frags[i], NULL, NULL);
     frags[i] = NULL;
   }
 }
@@ -134,7 +134,7 @@
 #if DETAILS
       FPRINTF (stderr, "%s",  "@");    /* good ACK */
 #endif
-      GNUNET_FRAGMENT_context_destroy (frags[i]);
+      GNUNET_FRAGMENT_context_destroy (frags[i], NULL, NULL);
       frags[i] = NULL;
       acks++;
       return;
@@ -215,7 +215,9 @@
         htons (sizeof (struct GNUNET_MessageHeader) + (17 * i) % (32 * 1024));
     frags[i] = GNUNET_FRAGMENT_context_create (NULL /* no stats */ ,
                                                MTU, &trackers[i],
-                                               GNUNET_TIME_UNIT_SECONDS, msg,
+                                               GNUNET_TIME_UNIT_MILLISECONDS, 
+                                               GNUNET_TIME_UNIT_SECONDS, 
+                                              msg,
                                                &proc_frac, &frags[i]);
   }
 }

Modified: gnunet/src/include/gnunet_fragmentation_lib.h
===================================================================
--- gnunet/src/include/gnunet_fragmentation_lib.h       2012-10-22 12:34:03 UTC 
(rev 24450)
+++ gnunet/src/include/gnunet_fragmentation_lib.h       2012-10-22 12:36:41 UTC 
(rev 24451)
@@ -73,7 +73,9 @@
  * @param stats statistics context
  * @param mtu the maximum message size for each fragment
  * @param tracker bandwidth tracker to use for flow control (can be NULL)
- * @param delay expected delay between fragment transmission
+ * @param msg_delay initial delay to insert between fragment transmissions
+ *              based on previous messages
+ * @param ack_delay expected delay between fragment transmission
  *              and ACK based on previous messages
  * @param msg the message to fragment
  * @param proc function to call for each fragment to transmit
@@ -84,7 +86,8 @@
 GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
                                 uint16_t mtu,
                                 struct GNUNET_BANDWIDTH_Tracker *tracker,
-                                struct GNUNET_TIME_Relative delay,
+                                struct GNUNET_TIME_Relative msg_delay,
+                                struct GNUNET_TIME_Relative ack_delay,
                                 const struct GNUNET_MessageHeader *msg,
                                 GNUNET_FRAGMENT_MessageProcessor proc,
                                 void *proc_cls);
@@ -122,11 +125,15 @@
  * resources).
  *
  * @param fc fragmentation context
- * @return average delay between transmission and ACK for the
- *         last message, FOREVER if the message was not fully transmitted
+ * @param msg_delay where to store average delay between individual message 
transmissions the
+ *         last message (OUT only)
+ * @param ack_delay where to store average delay between transmission and ACK 
for the
+ *         last message, set to FOREVER if the message was not fully 
transmitted (OUT only)
  */
-struct GNUNET_TIME_Relative
-GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc);
+void
+GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc,
+                                struct GNUNET_TIME_Relative *msg_delay,
+                                struct GNUNET_TIME_Relative *ack_delay);
 
 
 /**

Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2012-10-22 12:34:03 UTC (rev 
24450)
+++ gnunet/src/transport/plugin_transport_udp.c 2012-10-22 12:36:41 UTC (rev 
24451)
@@ -128,8 +128,13 @@
   /**
    * expected delay for ACKs
    */
-  struct GNUNET_TIME_Relative last_expected_delay;
+  struct GNUNET_TIME_Relative last_expected_ack_delay;
 
+  /**
+   * desired delay between UDP messages
+   */
+  struct GNUNET_TIME_Relative last_expected_msg_delay;
+
   struct GNUNET_ATS_Information ats;
 
   size_t addrlen;
@@ -290,7 +295,7 @@
   size_t on_wire_size;
 
   unsigned int fragments_used;
-  struct GNUNET_TIME_Relative exp_delay;
+
 };
 
 
@@ -971,9 +976,9 @@
 static void
 free_session (struct Session *s)
 {
-  if (s->frag_ctx != NULL)
+  if (NULL != s->frag_ctx)
   {
-    GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag);
+    GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag, NULL, NULL);
     GNUNET_free (s->frag_ctx);
     s->frag_ctx = NULL;
   }
@@ -1236,7 +1241,8 @@
   s->addrlen = len;
   s->target = *target;
   s->sock_addr = (const struct sockaddr *) &s[1];
-  s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
+  s->last_expected_ack_delay = GNUNET_TIME_UNIT_SECONDS;
+  s->last_expected_msg_delay = GNUNET_TIME_UNIT_MILLISECONDS;
   s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS;
   s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO;
   start_session_timeout (s);
@@ -1561,17 +1567,17 @@
     frag_ctx->timeout = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), 
to);
     frag_ctx->payload_size = msgbuf_size; /* unfragmented message size without 
UDP overhead */
     frag_ctx->on_wire_size = 0; /* bytes with UDP and fragmentation overhead */
+    fprintf (stderr, "New fc with msg delay: %llu and ack delay %llu\n",
+            (unsigned long long )s->last_expected_msg_delay.rel_value,
+            (unsigned long long )s->last_expected_ack_delay.rel_value);
     frag_ctx->frag = GNUNET_FRAGMENT_context_create (plugin->env->stats,
-              UDP_MTU,
-              &plugin->tracker,
-              GNUNET_TIME_relative_max (s->last_expected_delay, 
GNUNET_TIME_UNIT_SECONDS),
-              &udp->header,
-              &enqueue_fragment,
-              frag_ctx);
-
-    frag_ctx->exp_delay = s->last_expected_delay;
-    s->frag_ctx = frag_ctx;
-
+                                                    UDP_MTU,
+                                                    &plugin->tracker,
+                                                    
s->last_expected_msg_delay, 
+                                                    
s->last_expected_ack_delay, 
+                                                    &udp->header,
+                                                    &enqueue_fragment,
+                                                    frag_ctx);    
     GNUNET_STATISTICS_update (plugin->env->stats,
                               "# UDP, fragmented msgs, messages, pending",
                               1, GNUNET_NO);
@@ -1964,7 +1970,9 @@
        "Message full ACK'ed\n",
        (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender),
        GNUNET_a2s ((const struct sockaddr *) addr, fromlen));
-  s->last_expected_delay = GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag);
+  GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag,
+                                  &s->last_expected_msg_delay,
+                                  &s->last_expected_ack_delay);
 
   if (s->addrlen == sizeof (struct sockaddr_in6))
   {
@@ -1994,15 +2002,6 @@
       udpw = tmp;
     }
   }
-/*
-  LOG (GNUNET_ERROR_TYPE_ERROR,
-       "Fragmented message sent: fragments needed: %u , payload %u bytes, used 
on wire %u bytes, overhead: %f, expected delay: %llu\n",
-       s->frag_ctx->fragments_used,
-       s->frag_ctx->payload_size,
-       s->frag_ctx->on_wire_size,
-       ((float) s->frag_ctx->on_wire_size) / s->frag_ctx->payload_size,
-       s->frag_ctx->exp_delay.rel_value);
-*/
   dummy.msg_type = MSG_FRAGMENTED_COMPLETE;
   dummy.msg_buf = NULL;
   dummy.msg_size = s->frag_ctx->on_wire_size;
@@ -2190,7 +2189,9 @@
           LOG (GNUNET_ERROR_TYPE_DEBUG,
                "Fragment for message for peer `%s' with size %u timed out\n",
                GNUNET_i2s(&udpw->session->target), 
udpw->frag_ctx->payload_size);
-          udpw->session->last_expected_delay = GNUNET_FRAGMENT_context_destroy 
(udpw->frag_ctx->frag);
+         GNUNET_FRAGMENT_context_destroy (udpw->frag_ctx->frag,
+                                          
&udpw->session->last_expected_msg_delay,
+                                          
&udpw->session->last_expected_ack_delay);
           GNUNET_free (udpw->frag_ctx);
           udpw->session->frag_ctx = NULL;
 

Modified: gnunet/src/transport/plugin_transport_wlan.c
===================================================================
--- gnunet/src/transport/plugin_transport_wlan.c        2012-10-22 12:34:03 UTC 
(rev 24450)
+++ gnunet/src/transport/plugin_transport_wlan.c        2012-10-22 12:36:41 UTC 
(rev 24451)
@@ -790,7 +790,7 @@
     GNUNET_HELPER_send_cancel (fm->sh);
     fm->sh = NULL;
   }
-  GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
+  GNUNET_FRAGMENT_context_destroy (fm->fragcontext, NULL, NULL);
   if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
   {
     GNUNET_SCHEDULER_cancel (fm->timeout_task);
@@ -857,10 +857,13 @@
   fm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   fm->cont = cont;
   fm->cont_cls = cont_cls;
+  /* 1 MBit/s typical data rate, 1430 byte fragments => ~100 ms per message */
   fm->fragcontext =
     GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
                                    &plugin->tracker,
                                    GNUNET_TIME_UNIT_SECONDS,
+                                   GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS,
+                                                                  100),
                                    msg,
                                    &transmit_fragment, fm);
   fm->timeout_task =




reply via email to

[Prev in Thread] Current Thread [Next in Thread]