【问题标题】:How is processor speed distributed across threads?处理器速度如何跨线程分布?
【发布时间】:2013-07-19 18:47:58
【问题描述】:

目标: 我试图估计我的代码在多个线程中同时运行时的执行速度。

问题 1)

如果我确切地知道我的代码在一个线程中针对单个请求运行的速度有多快,那么他们有什么方法可以估计它在多个线程中的运行速度吗?

问题 2)

其他线程的存在对其他线程的执行速度有什么影响(如果有的话)?

我的情况:

我遍历内存中最坏情况大小为 100 万个节点的图。它只是一次访问 100 万个内存地址 1。在 1 个线程上需要半秒钟,我担心这将如何随着多个用户执行相同的查询而扩展。每个用户请求都由一个单独的线程处理,因此 100 个并发用户将需要 100 个并发线程。每个线程共享相同的资源,但只读。没有写作。有没有机会让每个用户看到大致相同的执行时间?

注意:我知道这取决于许多因素,但如果您发现代码需要 x 给定 x 硬件的单个线程的时间量。最后,我想补充一点,我对计算机硬件架构以及多线程如何在后台工作的经验有限。

【问题讨论】:

标签: multithreading web-applications benchmarking


【解决方案1】:

这些都是有趣的问题,但遗憾的是,没有直截了当的答案,因为答案取决于很多不同的因素。

大多数现代机器都是多核的:在理想的情况下,四线程进程能够在四核机器中几乎线性扩展(即运行速度是四倍) .

不过,大多数程序大部分时间都在等待:磁盘或数据库访问、内存总线、网络 I/O、用户输入和其他资源。更快的机器通常不会使这些事情变得更快。

大多数现代操作系统(包括 Windows、Unix/Linux 和 MacOS)使用处理器的方式是通过或多或少的循环方式将处理器时间安排给进程和线程:在任何给定时间可能是正在等待处理器时间的线程(这有点简单,因为它们都有一些进程优先级的概念,因此高关键性进程比不太重要的进程更早地被推入队列)。

当一个线程正在使用一个处理器内核时,只要它的时间片持续,它就会全部得到它:实际上,一次只有一件事实际上在单个内核上运行。当进程用完它的时间片,或者请求一些不能立即可用的资源时,它在处理器核心的轮次结束,下一个计划任务将开始。这往往会非常优化地利用处理器资源。

那么,决定流程扩大规模的因素有哪些?

  • 单个进程花费多少运行时间等待 I/O 和用户输入?

  • 是多个线程访问相同资源还是不同的资源?

  • 线程之间必须进行多少通信?在单个线程和您的进程主线程之间?这需要同步,并引入等待。

  • 活动线程的热点有多“紧”?它的主体可以放入处理器的内存中,还是必须访问(慢得多的)总线内存?

作为一般规则,单个线程彼此之间的独立程度越高,您的应用程序扩展的线性度就越高。然而,在现实世界的商业应用程序中,情况远非如此。提高流程扩展能力的最好方法是理解它——以及它的依赖关系——然后使用分析器找出最等待的地方,看看你是否可以设计技术策略来避免它们。

【讨论】:

    【解决方案2】:

    如果我确切地知道我的代码在一个线程中针对单个请求运行的速度有多快,那么他们有什么方法可以估计它在多个线程中的运行速度吗?

    不,您应该凭经验确定。

    其他线程的存在对其他线程的执行速度有什么影响(如果有的话)?

    计算密集型任务可能会很好地扩展,并且大部分独立于其他线程。有趣的是,some CPU manufacturers implement features which can increase the clock of a lone-busy CPU core to compensate for the all the idle cores。此类功能可能会混淆您对缩放的测量和期望。

    缓存/内存/磁盘绑定任务将开始相互竞争,除非存在资源分区。

    我知道这取决于许多因素

    绝对!因此,我建议您对其进行原型制作并进行测量。然后找出为什么它没有像你希望的那样扩展并尝试不同的算法。迭代。

    但肯定有一些方法可以确定您的代码是否可以扩展

    是的,但不幸的是,它需要对代码实现的算法进行详细描述。您的结果将在很大程度上取决于您的代码活动在这些一般区域中的比率,以及您的目标在这些区域中的能力:

    • 磁盘 I/O
    • 网络 I/O
    • 内存 I/O
    • 计算

    我的情况:我的应用程序在一个应用服务器中运行,该服务器为每个用户请求分配一个线程。如果我的应用程序在 2 秒内为 1 个用户执行,我不能假设如果 100 个用户同时运行相同的操作,它总是需要 2 秒对吗?

    如果您的应用服务器为每个用户请求计算 pi 到 100 位,它可能会很好地扩展,直到您遇到目标的核心限制。

    如果您的应用服务器为每个用户请求执行数据库查询,它可能只会扩展,并且目标硬件可以承受必要的负载。

    编辑给定的细节:

    我遍历内存中最坏情况大小为 100 万个节点的图。它只是一次访问 100 万个内存地址。

    您的问题听起来是内存+缓存绑定的。您应该研究目标 CPU/mem 部署的详细信息,或者如果您正在设计它,请选择高内存吞吐量。

    • NUMA 系统(内存的“资源分区”)可能会最大化您的整体并发内存吞吐量。请注意,由于您的问题似乎要求同时访问相同的内存页面,NUMA 系统会惩罚执行远程内存访问的进程。在这种情况下,请考虑在初始化时创建多个数据副本。
    • 根据遍历模式,TLB 压力可能是一个因素。考虑尝试使用大(又称“大”)页面。
    • 缓存争用也可能是扩展的一个因素。
    • 您的特定算法很容易最终支配任何特定系统效应,具体取决于最佳情况和最差情况之间的距离。

    对计算机硬件架构以及多线程如何在后台工作的经验有限。

    使用 CPU 性能计数器和 Intel 的 VTune、perfoprofile 等工具来分析查询。它可以告诉您在代码中执行昂贵操作的位置。使用此信息,您可以优化查询以使其表现良好(单独和总体)。

    【讨论】:

    • 资源依赖的优点。我刚刚在“我的情况”部分添加了对我正在尝试做的事情的更详细描述。鉴于您关于资源依赖的观点,您是否还有其他意见?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多