简体   繁体   English

如何只使用您的程序可用的带宽

[英]How to only barely use the bandwidth available to your program

I am making a program that will download a bunch of different items. 我正在制作一个程序,将下载一堆不同的项目。 My language has cheap concurrency, so I first thought that I could download them all at once. 我的语言具有廉价的并发性,所以我首先想到我可以一次下载它们。 Problem is using concurrency you don't have is bad . 问题是使用你没有的并发性是不好的 If I tried downloading them all at once, the user would have to wait for all of them before getting any of them. 如果我尝试一次性下载它们,用户必须等到所有这些才能获得它们之前。

Let's say that you are downloading 10 items that can be downloaded at 7 mb/s, and you have 20 mb/s of download speed. 假设您正在下载10个可以以7 mb / s的速度下载的项目,并且您的下载速度为20 mb / s。 The program should start downloading only the first three items, and will only start downloading new items once old items have finished and there is bandwidth. 该程序应该只开始下载前三项 ,并且只有在旧项目完成且有带宽后才开始下载新项目。 Note also that in general the items won't have the same download speed. 另请注意,一般情况下,项目的下载速度不同。

If I had some programmatic way to check network saturation, this would be easy (just check if its saturated before spawning new threads.) 如果我有一些程序化的方法来检查网络饱和度,这将很容易(只需检查它是否在产生新线程之前已经饱和。)

As has been pointed out in the comments, you can't do this well enough to make any guarantees. 正如评论中指出的那样,你做得不够好,无法做出任何保证。 But, suppose you want to do your best, anyways. 但是,无论如何,假设你想要做到最好。

There are two parts to this problem: 这个问题有两个部分:

  1. Determine the bandwidth available. 确定可用带宽。
  2. Control the bandwidth being consumed. 控制正在消耗的带宽。

Roughly controlling the bandwidth consumed can be accomplished in a user space program by limiting the rate at which you read from the socket. 通过限制从套接字读取的速率,可以在用户空间程序中大致控制所消耗的带宽。 The TCP/IP stack will notify the other end of the connection that the queue is is maintaining on your application's behalf has gotten full, and nothing more will be sent. TCP / IP堆栈将通知连接的另一端,该队列正在代表您的应用程序进行维护,并且不会再发送任何其他内容。 A convenient way of implementing that rate limiting is with token buckets . 实现速率限制的便捷方式是使用令牌桶

Quick token bucket implementation: 快速令牌桶实施:

 int bucket = 0;
 start_thread({ while(transfer_in_progress) {
                    bucket += bytes_per_second_limit;
                    sleep(1);
                });
 while(transfer_in_progress) {
    bytesread = read(socket, buffer, min(bucket, buffersize), );
    bucket -= bytesread;
 }

If bytes_per_second_limit is set to roughly the bandwidth available, expressed in bytes/second, then that should read as fast as the connection allows. 如果bytes_per_second_limit大致设置为可用带宽(以字节/秒表示),则应该以连接允许的速度读取。 If the connection is faster, you'll be limited to bytes_per_second_limit . 如果连接速度更快,您将被限制为bytes_per_second_limit If the connection is slower , then bucket will grow forever, at a rate proportional to the difference between the speed limit, and the available bandwidth. 如果连接速度较慢 ,则bucket将以与速度限制和可用带宽之间的差异成比例的速度永久增长。

Hmm! 哼!

If you run another thread, and keep an eye on bucket , you can watch for two conditions: 如果您运行另一个线程,并密切关注bucket ,您可以观察两个条件:

  1. If bucket is always 0, then there is more bandwidth available, and you can increase bytes_per_second_limit , limited perhaps by your most recent best guess for available bandwidth (from #2). 如果bucket始终为0,则可用带宽更多,并且可以增加bytes_per_second_limit ,可能受限于您最近对可用带宽的最佳猜测(来自#2)。 Or start an additional download. 或者开始额外下载。
  2. If bucket is larger than the last time you looked, and the last few seconds of data points appear to indicate continuing growth (maybe do a linear regression; whatever you like), the rate of that growth expressed in bytes/second is how much you can reduce bytes_per_second_limit by in order to match your download rate with the available bandwidth. 如果bucket大于您上次查看的时间,并且数据点的最后几秒似乎表示持续增长(可能进行线性回归;无论您喜欢什么),以字节/秒表示的增长率是多少可以减少bytes_per_second_limit ,以使您的下载速率与可用带宽相匹配。

The problem with all this is that there is no guarantee your bandwidth will stay constant. 所有这一切的问题在于无法保证您的带宽保持不变。 The thread monitoring bucket might bounce back and forth between increasing the rate, and limiting it. 线程监控bucket可能会在增加速率和限制速率之间来回反弹。 I'd suggest you start by averaging over at least 10 or 20 seconds before making rate limit changes. 我建议您在进行速率限制更改之前,先平均至少10或20秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM