HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

如何让代码并发效率更高

  • 2013-08-13
  • 本文字数:2197 字

    阅读完需:约 7 分钟

随着计算硬件的快速发展,多核多处理器已经广泛应用于企业和个人环境中,开发人员利用多线程技术努力提高软件的计算速度,资深系统架构师 Gurudutt Kumar总结了如何让代码并发效率更高的实践经验。

Gurudutt 首先列举了几种影响软件可伸缩性的问题:

  • 效率低下的并行化:单片应用程序或软件无法有效使用可用的计算资源。您需要将应用程序组织成并行任务。在传统的不支持多线程的应用程序或软件中,我们会经常看到这个问题。这些应用程序在多核、多处理器、芯片多线程硬件上无法伸缩,并且无法实现更好的吞吐量。线程太多可能会和线程太少一样,都不会产生好的结果。
  • 串行瓶颈:在多个线程或进程之间共享数据结构的应用程序可能会有串行瓶颈。为了保持数据完整性,可能必须使用锁定和串行化技术(例如,读取锁、读写锁、写入锁、自旋锁、互斥等)将这些共享数据结构的访问串行化。设计得效率低下的锁可能会由于多个线程或进程之间的高度锁争用而导致串行瓶颈,从而尝试获取锁。这可能会潜在地降低应用程序或软件的性能。应用程序的性能可能会随着核心或处理器数量的增加而降低。
  • 对操作系统 (OS) 或运行时环境的过度依赖:您不能依赖操作系统、运行时环境或编译器来完成伸缩应用程序或软件所需的一切操作。但是,编译器和运行时环境可以帮助提供一定的优化,您不能依赖它们解决所有可伸缩性问题。例如,不能依赖 Java™ 虚拟机 (JVM) 通过自动并行来发现 Java 应用程序的最佳可伸缩的机会。
  • 工作负载的不平衡可能是一个瓶颈:工作负载的不均匀分布可能导致无法有效地利用计算资源。您可能必须将较大的任务划分成可以并行运行的较小的任务,还可能必须将串行算法更改为并行算法,以便提高性能和可伸缩性。
  • I/O 瓶颈:由于阻止磁盘输入 / 输出 (I/O) 或高网络延迟而导致的瓶颈可能会严重抑制应用程序的可伸缩性。
  • 无效的内存管理:在多核平台上,因为有很多处理单元,因此纯计算可能非常廉价,并且主要内存可能也不是问题,因为它正在变得越来越大。但是,内存带宽一直是一个瓶颈,因为所有处理器核心都贡献了一个通用的总线。无效的内存管理可能导致一些难以检测到的性能问题,比如伪共享。

以“避免内存争用”为例,Gurudut 做了解释:

在内存和缓存中,各种不同的核共享一个通用的数据区域,这需要在它们之间进行同步。当不同的核同时访问同一个数据区域时,会发生 _ 内存争用 _。在不同的核之间同步数据会因总线通信、锁定成本以及缓存缺失而有很大的性能损失。如果应用程序有多个线程,并且所有线程都更新或修改同一个内存地址,那么正如前面部分所讨论的那样,为了保持缓存一致性,可能会产生一次重大的乒乓效应。这会导致性能降低。

如何避免内存争用呢?Gurudut 认为“不要在核之间共享可写入的状态”:

  • 为了最大程度地减少内存总线通信,可以通过最小化共享位置 / 数据尽可能地减少核心交互,即使共享数据没有锁保护,而有一些硬件级别原子指令(如 Microsoft® Windows® 32 位平台上的 InterlockedExchangeAdd64)保护也是如此。
  • 减少线程之间的内存争用的一个方法是从多个线程中消除对共享内存区域的更新。例如,即便是在多个线程需要更新全局计数器或累计总数(如统计数据)时,各个线程也可以保持线程本地总数,并让全局总数仅在需要时通过一个通用的线程进行更新。因此,在共享内存区域上的争用会大大减少。
  • 趋向于减少锁争用的模式会减少内存通信,因为它是一个共享的可写入状态,该状态需要使用锁并产生争用。

对于锁争用,Gurudut 认为要从“避免”和“减少”两个方面来解决这个问题:

避免

  • 避免在数据结构中发生锁争用的方法之一是采用并发数据结构设计和无锁算法,这会消除锁以及传统的同步技巧(比如互斥)。有多种并发数据结构的设计并不需要利用同步机制,比如互斥。
  • 无锁算法的一些示例如下:
    • 使用 相对论编程 的可伸缩并发哈希表:该技巧的最简单示例是 Read Copy Update (RCU) ,它专用于 Linux 内核,大大提高了 Linux 内核的性能,并简化了 Linux 内核的代码。
    • 无锁可扩展有序分割的哈希列表:这个无锁递归可扩展哈希算法使用了无锁的链接列表,这些列表使用原子指令来修改链接的列表。
  • 在 Linux 内核中,广泛使用了每处理器变量,系统上的每个处理器都获得了自己的一个给定变量的副本。访问每处理器变量不需要使用锁,此外,因为在不同的处理器上,这些变量未在线程之间共享,因此没有伪共享或内存争用。这种技巧非常适合收集统计信息。

减少

  • 当使用传统锁或同步技巧(如自旋锁)时,必须注意的是,不要使用单片锁或全局锁,而是将这些锁分成更细小的部分。因此,锁会保护数据结构中的某个特定区域以及较小的区域。这样多个线程就能够通过获取保护这些成员的相应锁,在同一数据结构的不同成员上并发进行操作。这种方法可以实现更多并发。
  • 甚至当软件设计中的同步机制能够实现更好的并发和减少锁争用时,也可能会由于伪共享而导致发生性能问题。例如,考虑一个哈希数据结构。如果存在一个自旋锁数组,用于保护哈希中的每个哈希桶,那么在自旋锁数组中可能会出现伪共享。两个线程在两个不同的处理器上运行,每个线程都锁定哈希中的不同哈希桶,那么当它们所需的自旋锁位于同一个缓存行上时,可能会发生伪共享。因此,在设计此类算法时需要考虑采用避免发生伪共享的通用技巧。

作者的微信公众号“老崔瞎编”,关注 IT 趋势,承载前沿、深入、有温度的内容。感兴趣的读者可以搜索 ID:laocuixiabian,或者扫描下方二维码加关注。

2013-08-13 03:156092
用户头像

发布了 501 篇内容, 共 255.9 次阅读, 收获喜欢 60 次。

关注

评论

发布
暂无评论
发现更多内容

在矿山“土壤”种植大模型,云鼎科技向产业狂奔这一年

脑极体

AI

使用 Hugo 快速搭建一个云博客系统

左诗右码

Hugo

C# 使用模式匹配的好处,因为好用所以推荐~

EquatorCoco

C# C语言

时序数据库如何选型?详细指标总结!

Apache IoTDB

如何借助Redis巧妙的管理用户签到?——Bitmap篇

左诗右码

redis'

云手机解决海外社媒风控问题

Ogcloud

云手机 海外云手机 跨境云手机 云手机推荐 海外社媒运营

活动报名丨智源研究院与行业数据应用Workshop

智源研究院

天润融通新品上线:坐席知识推荐,让客服工作更轻松!

天润融通

人工智能

天润融通荣获2023 CEIA 中国企业IT大奖

天润融通

客户在哪儿AI的企业全历史行为数据与企业信息查询平台上的数据有何区别

客户在哪儿AI

ToB营销 ToB获客 ToB增长 ToB销售 大客户营销

⾯向现代分层存储的 Caching 技术漫谈|Data Infra 研究社第十九期(含资料发布)

Databend

2024年,是该掌握双拼打字的时候了!

左诗右码

Altair 首席技术官:数据分析和人工智能平台帮助企业创造更好、更安全、更可持续的产品

Altair RapidMiner

人工智能 算法 数据分析 altair

从基础到高级应用,详解用Python实现容器化和微服务架构

快乐非自愿限量之名

Python 微服务 容器化

国内外API平台对比:RapidAPI、聚合数据、API云市场、幂简集成

幂简集成

API API工具

如何借助Redis更高效统计UV?——Hyperloglog篇

左诗右码

redis'

@所有人,2024华为ICT大赛基础软件实践训练营来了!时间有限,别错过!

轶天下事

ETL数据集成丨通过ETLCloud工具,将Oracle数据实时同步至Doris中

RestCloud

oracle Doris 数据同步 ETL ETLCloud

吐血整理如何在Google Earth Engine上写循环 五个代码实例详细拆解

EquatorCoco

Google 文件整理

怎样利用海外云手机进行引流?

Ogcloud

云手机 海外云手机 云手机海外版 电商云手机 跨境云手机

CSS:弹性布局(display:flex)

不在线第一只蜗牛

CSS 前端 布局

如何在Redis中快速推算两地之间的距离?——Geo篇

左诗右码

redis'

阿里发布革新的音频多模态模型 Qwen2-Audio;月之暗面回应大模型显示「9.11 大于 9.9」丨 RTE 开发者日报

声网

NVIDIA GPU 监控观测最佳实践

观测云

gpu

酷克数据出席 2024 可信数据库发展大会 存算分离架构驱动电信行业数据平台革新

酷克数据HashData

新MacBook到手时,建议你需要做的事情(二)

左诗右码

Mac

国产大模型加持,科大讯飞-讯飞晓医APP当前累计下载量1200万

EVANjesse

AI 智慧医疗 科大讯飞 讯飞星火 国产大模型

新MacBook到手时,建议你需要做的事情(一)

左诗右码

Mac

大模型评测技术研讨会暨国际标准IEEE P3419第二次工作组会议成功召开

智源研究院

如何让代码并发效率更高_语言 & 开发_崔康_InfoQ精选文章