Ralentir un débit

Souvent lorsque nous utilisons des ressources sur un ordinateur, nous désirons contrôler la vitesse du flux de données. Par exemple, quand nous téléchargeons des fichiers sur des systèmes peer to peer, nous ne voulons pas utiliser toute notre bande passante pour envoyer les fichiers aux autres. Aussi, lorsque nous copions des fichiers sur notre système, il est parfois intéressant de ne pas utiliser la vitesse maximale de transfert étant donné que tout le système est ralenti durant ce temps. Voici donc quelques algorithmes pour réaliser cette fonctionnalité.

La technique la plus simple est de compter la quantité de données envoyées et de remettre le compteur à zéro à chaque seconde qui s’écoule. En ayant ce compteur, il est ainsi possible de suspendre le transfert une fois la quantité maximale par seconde envoyée et de le repartir à la nouvelle seconde. Le gros problème de cette technique est que le système est utilisé à 100% au début de chaque seconde et à 0% vers la fin de la seconde.  Le mieux serait donc de répartir la transmission durant toute la seconde et non simplement tout transmettre au plus vite.

Voici ce à quoi ressemble le premier algorithme:

Et ceci est pour le second algorithme:

Il est évident que la charge est mieux distribuée dans le second exemple. Maintenant la question reste: « Comment réaliser cet algorithme? ». Pour commencer, nous devons choisir la taille du buffer que nous allons envoyer à chaque fois. Ensuite, en prenant la vitesse que nous désirons et en la divisant par la taille du buffer, nous savons le nombre de fois que nous pouvons envoyer des données pour chaque seconde. Si par exemple nous pouvons envoyer des données 5 fois en une seconde, cela veut dire que nous pouvons appeler la fonction d’envoi une fois par 200 millisecondes. Il suffit donc de mesurer le temps pris pour envoyer une fois le buffer et suspendre le processus durant le restant du temps alloué pour cet appel. Alors s’il faut 10 millisecondes pour envoyer le buffer, nous attendrons 190 millisecondes avant d’envoyer encore. Le pseudo-code ressemble à cice:

  • NbAppelsParSeconde =VitesseVoulue / TailleBuffer
  • TempsTotalAppel = 1000 / NbAppelsParSeconde
  • Depart = TempsCourantEnMillisecondes()
  • Envoyer(Buffer)
  • TempsAAttendre = TempsTotalAppel – (TempsCourantEnMillisecondes() – Depart)
  • Attendre(TempsAAttendre)