Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 上下文切换时间开始成为应用程序整个运行时的重要部分_Multithreading_Asynchronous_Epoll_Libevent - Fatal编程技术网

Multithreading 上下文切换时间开始成为应用程序整个运行时的重要部分

Multithreading 上下文切换时间开始成为应用程序整个运行时的重要部分,multithreading,asynchronous,epoll,libevent,Multithreading,Asynchronous,Epoll,Libevent,例如,一个操作系统进行上下文切换可能需要10微秒;如果线程在返回睡眠前只做了15微秒的工作,那么40%的运行时只是上下文切换 这是低效的,当你的硬件、电源和冷却成本达到最高水平时,这种低效的现象就开始显现出来。线程数少意味着操作系统不需要像这样切换上下文 因此,在您的情况下,如果您的要求是计算机处理10000个连接,并且您有8个核心,那么效率最佳点将是每个核心1250个连接 每个线程有更多的客户端 在服务器处理客户机请求的情况下,它取决于处理每个客户机所涉及的工作量。如果这是一个很小的工作量,那

例如,一个操作系统进行上下文切换可能需要10微秒;如果线程在返回睡眠前只做了15微秒的工作,那么40%的运行时只是上下文切换

这是低效的,当你的硬件、电源和冷却成本达到最高水平时,这种低效的现象就开始显现出来。线程数少意味着操作系统不需要像这样切换上下文

因此,在您的情况下,如果您的要求是计算机处理10000个连接,并且您有8个核心,那么效率最佳点将是每个核心1250个连接

每个线程有更多的客户端

在服务器处理客户机请求的情况下,它取决于处理每个客户机所涉及的工作量。如果这是一个很小的工作量,那么每个线程都需要处理来自多个客户端的请求,这样应用程序就可以在没有大量线程的情况下处理大量客户端

在网络服务器中,这意味着熟悉select()或epoll()系统调用。调用时,这两个函数都将使线程处于休眠状态,直到上述文件描述符中的一个以某种方式就绪。但是,如果没有其他线程在运行时纠缠操作系统,那么操作系统就不一定需要执行上下文切换;线程可以坐在那里打瞌睡,直到有事情要做(至少这是我对操作系统的理解。每个人,如果我错了,请纠正我!)。当一些数据从客户端出现时,它可以更快地恢复

这当然会使线程的源代码更加复杂。例如,您不能从客户端执行数据的阻塞读取;epoll()告诉您文件描述符已准备好读取,但这并不意味着您希望从客户端接收的所有数据都可以立即读取。如果线程由于影响多个客户端的错误而暂停。但这是为获得尽可能高的效率所付出的代价

而且,您不一定只希望8个线程与8个内核和10000个连接一起使用。如果您的线程每次处理单个连接时都必须为每个连接执行某些操作,则需要将开销降至最低(通过每个线程拥有更多线程和更少连接)。[select()系统调用是这样的,这就是epoll()被发明的原因。]您必须平衡这一开销与上下文切换的开销

在Linux中,10000个文件描述符对于单个进程来说太多了(太多了?),因此您可能需要多个进程而不是多个线程。还有一个小问题是,无论您的系统有什么响应时间/连接要求,硬件是否基本上能够支持10000。如果不这样做,您将被迫在两个或多个服务器上分发应用程序,这可能会变得非常复杂

准确理解每个线程要处理多少个客户机取决于处理过程是什么,是否涉及硬盘活动,等等,所以没有一个单一的答案;它对于不同的应用程序是不同的,对于不同机器上的相同应用程序也是不同的。调整客户机/线程以达到最高效率是一项非常困难的工作。这就是Solaris上的dtrace、Linux上的ftrace等评测工具(特别是当使用like时,我在x86硬件上的Linux上使用了很多),因为它们允许您非常精确地理解线程处理客户端请求时所涉及的运行时

像谷歌这样的公司当然非常注重效率;他们通了很多电。我收集到,当谷歌选择一个CPU、硬盘驱动器、内存等放进他们著名的国产服务器时,他们用“每瓦搜索数”来衡量性能。很明显,在你变得对事情那么挑剔之前,你必须是一个相当大的服装,但这是事情最终的发展方向

其他效率

处理诸如TCP网络连接之类的事情本身可能会占用大量CPU时间,并且很难理解系统中所有CPU运行时的去向。对于网络连接,更智能的NIC中的TCP卸载等功能可以带来真正的好处,因为这将CPU从纠错计算等操作的负担中解放出来

TCP卸载反映了我们在高速大规模实时嵌入式信号处理领域所做的事情。我们使用的(奇怪的)互连需要零CPU时间来运行它们。因此,所有的CPU时间都用于处理数据,专门的硬件负责移动数据。这带来了一些相当惊人的效率,因此人们可以构建一个更温和、成本更低、耗电更少的CPU系统


语言也会对效率产生根本性的影响;像Ruby、PHP、Perl这样的东西都很好,但是每个人最初都使用它们,但后来迅速成长,最终会变成更高效的东西,比如java/Scala、C++等等。

< P>你的问题甚至比你想象的还要好!P

如果使用libevent进行联网,它可以在套接字上进行非阻塞I/O一个线程可以做到这一点(使用一个内核),但这会降低CPU的利用率

但是如果您执行“重”文件I/O,那么内核就没有非阻塞接口。(许多系统根本不做这件事,其他系统在这一领域还有些不成熟的东西,但不可移植。-Libevent不使用这一点。)-如果文件I/O是程序/测试的瓶颈,那么更多的线程将是有意义的!如果使用硬盘,i/o调度程序