【GO 语言】合理配置 GOMAXPROCS 提升一倍以上的性能

本贴最后更新于 2411 天前,其中的信息可能已经东海扬尘

GOMAXPROCS 用默认的,就是 CPU 的硬件线程数目,

对于大部分 File IO 密集的应用是不合适的。

至少应该配置到硬件线程数目的 5 倍以上, 最大 1024。

具体参见

这是为什么呢?

我们来复习下 Go 的线程模型,M/P/G 三种对象,分别代表 操作系统线程、协程执行令牌、协程;

在任何情况下,Go 运行时并行执行(注意,不是并发)的 goroutines 数量是小于等于 P 的数量的。

如果一个持有 P 的 M,由于 P 当前执行的 G 调用了 syscall 而导致 M 被阻塞,那么:

注意

注意

注意

关键点:此时,GO 的调度器是迟钝的,它很可能什么都没做,直到 M 阻塞了想当长时间以后,才会发现有一个 P/M 被 syscall 阻塞了。然后,才会用空闲的 M 来强这个 P。

补充说明:调度器迟钝不是 M 迟钝,M 也就是操作系统线程,是非常的敏感的,只要阻塞就会被操作系统调度(除了极少数自旋的情况)。但是 GO 的调度器会等待一个时间间隔才会行动,这也是为了减少调度器干预的次数。也就是说,如果一个 M 调用了什么 API 导致了操作系统线程阻塞了,操作系统立刻会把这个线程 M 调度走,挂起等阻塞解除。这时候,Go 调度器不会马上把这个 M 持有的 P 抢走。这就会导致一定的 P 被浪费了。

这就是为何,GOMAXPROCS 太小,也就是 P 的数量太少,会导致 IO 密集(或者 syscall 较多)的 go 程序运行缓慢的原因

那么,GOMAXPROCS 很大,超过硬件线程的 8 倍,会不会有开销呢?

答案是,开销是有的,但是远小于 Go 运行时迟钝的调度 M 来抢夺 P 而导致 CPU 利用不足的开销。

P.S.

本文至少对 Go 1.8 版本是有效的。

P.S.

其实,这也是经典的长肥管道问题,由于 SSD 的普及,IO 操作从高延时低吞吐,变成了中高延时高吞吐。

一次 SSD IO 的延时在 1ms,而一块企业级 SSD 的吞吐在 100Kops,那么在队列里面的操作就有 100 个。

操作系统在 1ms 内可以完成很多次线程调度(一般情况 1ms 可以完成几十次线程调度),但是 Go 的运行时,最大的阻塞发现延时是 10ms。

于是,当一个 Go 的协程发起一次 SSD IO 时,执行该 G 的 M 会阻塞然后被 OS 调度走,该 M 一直持有 P。在 1ms 内,这次 SSD IO 很可能不会完成。Go 的运行时,最快在 20us,最慢在 10ms 会发现有一个 M 持有 P 并阻塞了。运气不好的话,很可能,Go 运行时 2ms 才扫描一次,于是没来得及发现这个阻塞的 M,阻塞就结束了。宝贵的 P 资源就这么被阻塞的 M 浪费了。SSD IO 的 ops 上限变成了

*P 的数量 (1s/IO 延时)

当 P 的数量小于 100,IO 延时 1ms 的时候,ops 就肯定小于 100Kops 了。

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1388 回帖 • 279 关注
  • 性能
    63 引用 • 180 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 估计要很久以后了。

  • 其他回帖
  • salamander

    我倒是在看 go 2.0 的泛型

    1 回复
  • 期待 Go 1.12 的新调度器,应该是一个抢占式的调度器。
    可以极大的减少 Go 的延时。

    1 回复
  • someone

    GOMAXPROCS 对于 GO 来说非常重要, 很多服务在高压力下,响应延时变大就是因为 GOMAXPROCS 设置的太小导致的.
    对于 8 个 Cores 的服务器,GOMAXPROCS 设置到 60 是比较合适的一般情况.

    1 回复
  • 查看全部回帖

推荐标签 标签

  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    728 引用 • 1273 回帖 • 1 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 232 回帖
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 667 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 140 关注
  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖 • 2 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 1 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 63 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    142 引用 • 442 回帖 • 1 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    288 引用 • 734 回帖 • 2 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 2 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    107 引用 • 295 回帖
  • 导航

    各种网址链接、内容导航。

    42 引用 • 175 回帖
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 1 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖 • 1 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2036 回帖
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 335 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    53 引用 • 37 回帖 • 3 关注
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    4 引用 • 16 回帖
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 559 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 635 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 172 关注
  • 自由行
    4 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    167 引用 • 1520 回帖
  • gRpc
    11 引用 • 9 回帖 • 69 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4601 回帖 • 700 关注