Rust中的高吞吐量流处理

本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序。

最后,作者介绍了如何通过测量空闲和阻塞时间来优化流处理程序的性能,并将这些内容同步至Twitter和blog。

图片

此外,作者还提供了一些其它方面的优化建议,例如:

  • 在实际系统中,应考虑将线程固定至CPU内核上或使用一种版本的绿色线程减少上下文切换。
  • 在处理流时,通常需要为结果分配内存。内存分配是昂贵的,所以,在以后的文章中,作者将会介绍一些优化内存分配的好方法。

首先,分别介绍下在同步和异步Rust中的流特质。

一、同步和异步Rust中的流特质

在同步Rust中,流核心抽象是Iterator。它提供了在序列中产生项的方法并在它们之间进行阻塞,然后,通过将迭代器传递给其它迭代器的构造函数完成组合。这使我们可以毫不费力地将事物连接在一起。

在异步Rust中,流核心抽象是Stream。它的行为与Iterator非常相似;但是,它并不是在每个项之间产生的阻塞,而是允许其它任务在阻塞等待时运行。

在异步Rust与同步Rust中,Read和Write分别对应AsyncRead和AsyncWrite。这些特质表明:未解析的字节通常直接来自10层(例如,来自套接字或文件)。

图片

Rust流吸收了其它语言所具备的最佳功能;例如,它们能通过利用Rust特质系统回避Node.js的Duplex流中出现的遗留问题,也能同时实施背压和惰性迭代,大大提升了效率。最重要的是,Rust流允许使用相同类型的异步迭代。

未来,关于Rust流还有很多值得关注之处,尽管仍有一些问题亟待解决。

二、总体概括:什么是流处理?

现在,也许你已经了解到了同步和异步Rust中的流特质,下面再来介绍下什么是“流处理”。

“流处理”是一种重要的大数据处理手段,其主要特点是处理的数据是源源不断且实时到来的。

在不同规模的科技公司中,流处理通常被用于分析和处理具体事件,且常被应用于分布式系统。

有些领域确实会大量使用“流处理”手段,包括:视频处理和高频交易。我们也能够借此寻找到新型区块链之中的架构灵感。因为,区块链需要处理交易和元数据流等。

如今,你可以租用具有100多个CPU的内核、100GB内存、多个GPU和100Gbps带宽的AWS实例,还无需拥有一个节点的分布式系统。

现在,让我们了解下流处理在Rust编程中的应用:

三、举个例子:计算10亿个数字的哈希程序

现在,让我们写一个用来计算10亿个数字的SHA512和BLAKE3哈希程序吧!你可以想象:数字代表交易、分析事件或价格信号。散列法可用来表示对这些输入的任意转换。

如下是单线程解决方案程序:

图片

当我在带有专用CPU和16核的Digital Ocean上用发布模式运行此程序时,只需6分钟多一点。

图片

1.通道

现在,让我们用“流处理”来重写这个程序。与在单个循环中执行散列不同,我们将设置一个线程管道并行执行散列,然后收集结果。

在两个线程之间发送数据的本地流被称为通道。我们的新程序将生成四个线程。生成器线程将生成数字并同时将它们发送至两个不同的哈希线程。散列线程将读取这些数字,分别对它们进行散列,然后将它们的输出发送给结果线程,下图是它的架构:

图片

我们也将使用标准库中的mpsc通道发送和接收数据。mpsc可用来表示“多生产者-单消费者”,代表你可以从多个线程向通道发送数据,但是,只有一个管道能够输出数据。虽然我们不会使用这个多制作人功能,但是了解这一点很重要。

它仍是一个相当简单的程序:

图片

输出结果如下:

图片

哦!带通道的新版本花费了两倍时间,这是怎么了?

2.环形缓冲器

你可以用火焰图进行测试,但还是省省时间吧!

无论多小,所有通道库的构建都会产生额外的费用,并行化所带来的好处必须大于此种开销,才能保证系统正常运作。这种情况下的瓶颈是通道send()和recv()。由于Rust中的标准库mpsc通道相对缓慢,但仍有其它替代方案,比如,crossbeam-channel。

为此,我们分析了4个不同的通道库,结果如下:

图片

显然,ringbuf和rtrb速度最快。因为它们的环形缓冲区无锁,扮演着“单个生产者-单个消费者”的角色。单个生产者意味着只有一个管道将数据放入队列,另一个管道将负责数据输出,这比“多生产者队列”开销小。

此外,这些程序库也是非阻塞式的。当队列已满时,如果尝试推送,它将提示“error”而不是“block”,“空队列”亦是如此。

为使用这些环形缓冲区库,我添加了自旋锁,以便在通道阻塞时继续重试。事实证明,这也是高频交易架构中所使用的方法。

我还发现,在等待时增加非常短的“休眠”时间整体性能就能提高。这可能是由于当核心使用率达到100%或高于某些温度时,启动CPU就会发生节流的现象。

如下是新的pop()和push(value)帮助器:

图片

我们将用新方法展示:

图片

速度确实比以前快了,但也快不了多少,现在,就让我们把并行化提升至另一个层次。

3.更多的并行化

目前,我们为哈希创建了两个线程,一个用于SHA512,另一个用于BLAKE3。两者中较慢的那个将成为我们技术发展的瓶颈。为证明这一点,我重新运行了原始的单线程示例,仅使用SHA512哈希,结果如下:

图片

这与并行哈希示例中的性能非常接近,意味着,总体上花在哈希上的大部分时间都是由SHA512产生。

那么,如果我们同时创建更多的线程并将多个数字进行散列排列呢?让我们试一试。我们将创建2个SHA512哈希线程和2个BLAKE3哈希线程来启动。

4.可视化

每个线程都拥有自己的输入和输出队列。我们将用循环顺序将生成的数字循环发送至每个线程并用相同的顺序读取结果。

图片

这确保了流的顺序能够在结果线程中维持不变;如果排序不重要或消息处理时间多变,那么,其它的调度机制可能会更好。

如下是循环调度代码:

图片

新的代码更复杂,部分如下:

图片

一起来看看,现在表现如何?输出结果如下:

图片

确实好多了!

5.测量“闲置”和“阻塞”时间

每个哈希函数应该有多少个线程?在更复杂的系统中,这很难确定,甚至可能是动态的。

实际上,有一种技术对“流处理”很有帮助,即,在某个时间窗口内测量空闲和阻塞时间。

  • 空闲时间

等待空队列接收消息所花的时间

  • 全程时间

等待满队列发送输出所花费的时间

空闲时间是pop()期间旋转的时间,阻塞时间是push()期间旋转的时间。我修改了这两个函数,用来跟踪花费时间。这段代码使用了开销很小的单元:

图片

我还创建了一个新的线程统计这些时间,输出结果如下:

图片

我们可以看到,sha512线程既没有“空闲”也没有“阻塞”,而是100%处于活跃状态;此外,我们还能通过增加sha512线程数量为系统提速。

注:当用测量系统的行为改变其性能时,可能会出现像“海森伯测不准原理”这样的问题。如果遇到此种情况,请查看“粗时间库”;通常,定时测量取近似值就足够了。

我们在Digital Ocean实例中,经过试验和错误数据总结出:最佳数量是8个SHA512线程和4个BLAKE3线程。

图片

结果:小于初始时间的1/6。

四、下一步:为不同的流处理结果分配内存

在这篇文章中,我们用具体实例介绍了Rust中流处理的概念、方法和优化,但是还有很多细节没有讨论。在实际系统中,我们应该考虑将“线程”固定到CPU内核上,用来减少上下文切换。

此外,在流处理时,你通常需要为不同的结果分配内存。这是昂贵的,所以,在今后的文章中,我们还将讨论这方面的一些策略。


多看看优秀的前沿工具

太空电梯、MOSS、ChatGPT等,都预兆着2023年注定不会是平凡的一年。任何新的技术都值得推敲,我们应要有这种敏感性。

这几年隐约碰过低代码,目前比较热门,很多大厂都相继加入。

低代码平台概念:通过自动代码生成和可视化编程,只需要少量代码,即可快速搭建各种应用。

到底啥是低代码,在我看来就是拖拉拽,呼呼呼,一通操作,搞出一套能跑的系统,前端,后端,数据库,一把完成。当然这可能是最终目标。

链接:www.jnpfsoft.com/?csdn,如果你感兴趣,也体验一下。

JNPF的优势就在于它能生成前后台代码,提供了极大的灵活性,能够创建更复杂、定制化的应用。它的架构设计也让开发者无需担心底层技术细节,能够专注于应用逻辑和用户体验的开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/24261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 实现账号诊断动画效果,逐条检测对应的项目

Dialog中的项目 逐条检测效果&#xff1a; 依赖库&#xff1a; implementation com.github.li-xiaojun:XPopup:2.9.19 implementation com.blankj:utilcodex:1.31.1 implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.101、item_account_check.xml <…

PictureBox基本使用

作用&#xff1a;展示图片&#xff0c;同时也具有click属性&#xff0c;可用充当按钮功能。 常用属性&#xff1a; 设置图片 设置图片的填充模式 常用事件&#xff1a; 后台代码示范&#xff1a;增加点击事件 private void pictureBox1_Click(object sender, EventArgs e){//…

【CodeWhisperer】亚马逊版代码生成工具

大家好&#xff0c;我是荷逸&#xff0c;今天给大家带来的是代码生成工具【CodeWhisperer】 CodeWhisperer简介 CodeWhisperer是亚⻢逊出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。 在编写代码时&#xff0c;它会自动根据我们现有的代码和注释生…

Java中「Future」接口详解

一、背景 在系统中&#xff0c;异步执行任务&#xff0c;是很常见的功能逻辑&#xff0c;但是在不同的场景中&#xff0c;又存在很多细节差异&#xff1b; 有的任务只强调「执行过程」&#xff0c;并不需要追溯任务自身的「执行结果」&#xff0c;这里并不是指对系统和业务产…

JDK, JRE和JVM之间的区别和联系

JDK, JRE和JVM是与Java编程语言相关的三个重要的概念&#xff0c;它们分别代表Java Development Kit&#xff08;Java开发工具包&#xff09;、Java Runtime Environment&#xff08;Java运行时环境&#xff09;和Java虚拟机&#xff08;Java Virtual Machine&#xff09;。它们…

大数据课程G2——Hbase的基本架构

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Hbase的基本架构; ⚪ 掌握Hbase的读写流程; ⚪ 掌握Hbase的设计与优化; 一、基本架构 1. HRegion 1. 在HBase中,会将一个表从行键方向上进行切分,切分成1个或者多个HRegion。 …

C#利用自定义特性以及反射,来提大型项目的开发的效率

在大型项目的开发过程中&#xff0c;需要多人协同工作&#xff0c;来加速项目完成进度。 比如一个软件有100个form&#xff0c;分给100个人来写&#xff0c;每个人完成自己的Form.cs的编写之后&#xff0c;要在Mainform调用自己写的Form。 如果按照正常的Form form1 new For…

MIT 6.824 -- MapReduce -- 01

MIT 6.824 -- MapReduce -- 01 引言抽象和实现可扩展性可用性(容错性)一致性MapReduceMap函数和Reduce函数疑问 课程b站视频地址: MIT 6.824 Distributed Systems Spring 2020 分布式系统 推荐伴读读物: 极客时间 – 大数据经典论文解读DDIA – 数据密集型应用大数据相关论文…

【具身智能】系列论文解读(CoWs on PASTURE VoxPoser Relational Pose Diffusion)

0. My Conclusion CoWs on PASTURE&#xff1a; 擅长零样本的视觉语言对象导航&#xff0c;主要解决了LLM辅助下的任务级动作执行任务VoxPoser&#xff1a; 擅长设计一些未预定义的动作轨迹&#xff0c;主要解决了LLM辅助下的动作轨迹设计任务Relational Pose Diffusion&#…

Packet Tracer - 将路由器连接到 LAN

Packet Tracer - 将路由器连接到 LAN 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 R1 G0/0 192.168.10.1 255.255.255.0 N/A G0/1 192.168.11.1 255.255.255.0 N/A S0/0/0 (DCE) 209.165.200.225 255.255.255.252 N/A R2 G0/0 10.1.1.1 255.255.255…

概率论与数理统计复习总结3

概率论与数理统计复习总结&#xff0c;仅供笔者复习使用&#xff0c;参考教材&#xff1a; 《概率论与数理统计》/ 荣腾中主编. — 第 2 版. 高等教育出版社《2024高途考研数学——概率基础精讲》王喆 概率论与数理统计实际上是两个互补的分支&#xff1a;概率论 在 已知随机…

Kernel Exception导致手机重启案例分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、高温触发 Kernel Exception 重启问题二、解决方案三、提高电池温度方案 一、 高温触发 Kernel Exception 重启问题 手机 电池温度 默认60度以上高温…

CBCGPRibbon 添加背景图片

resource.h中声明资源的ID&#xff1a;ID_RIBBON_BACKIMAGE rc文件中添加png图片路径&#xff1a; ID_RIBBON_BACKIMAGE PNG DISCARDABLE "res\\bkribbon.png" 代码中添加下测&#xff1a; //添加背景图片 m_wndRibbonBar.SetBackgroundImage(ID_RIB…

C语言单链表OJ题(较易)

一、移除链表元素 leetcode链接 题目描述&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 思路&#xff1a; 正常遍历&#xff0c;找到value的值与题目中相同的结点去fr…

第5集丨Vue 江湖 —— 监视属性/侦听属性

目录 一、基本使用1.1 watch配置监视1.2 vm.$watch动态监视1.3 深度监视(deep watch)1.4 简写形式 二、computed和watch的对比2.1 使用watch实现setTimeout操作2.2 用computed无法实现setTimeout 三、其他注意事项3.1 vue devtools的bug3.2 xxxyyy格式3.3 将window传入data中 V…

机器人开发--富锐雷达介绍

机器人开发--富锐雷达介绍 1 介绍参考 1 介绍 山东富锐光学科技有限公司是一家专注智能感知领域的激光雷达公司&#xff0c;致力于激光雷达前沿技术的开发和应用。 公司已累计完成数亿元融资&#xff0c;依托潍坊光电产业发展基础&#xff0c;自建生产线&#xff0c;达到年产…

LNMP安装

目录 1、LNMP简述&#xff1a; 1.1、概述 1.2、LNMP是一个缩写词&#xff0c;及每个字母的含义 1.3、编译安装与yum安装差异 1.4、编译安装的优点 2、通过LNMP创建论坛 2.1、 安装nginx服务 2.1.1、关闭防火墙 2.1.2、创建运行用户 2.1.3、 编译安装 2.1.4、 优化路…

Portraiture 4.0.3 for windows/Mac简体中文版(ps人像磨皮滤镜插件)

Imagenomic Portraiture系列插件作为PS磨皮美白必备插件&#xff0c;可以说是最强&#xff0c;今天它更新到了4.0.3版本。但是全网都没有汉化包&#xff0c;经过几个日夜汉化&#xff0c;终于汉化完成可能是全网首个Portraiture 4的汉化包&#xff0c;请大家体验&#xff0c;有…

展示Streamlit文本魔力(六):从头顶到脚尖

文章目录 1 前言✨2 st.markdown - 引入丰富的Markdown文本3 st.title - 引入引人注目的大标题4 st.header - 引入简洁的小标题5 st.subheader - 添加次级标题6 st.caption - 添加解释性文字7 st.code - 显示代码块8 st.text - 显示文本9 st.latex - 显示LaTeX公式10 st.divide…

【JAVA】 javaSE中的数组|数组的概念使用

数组的概念 什么是Java中的数组 数组&#xff1a;可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。在java中&#xff0c;包含6个整形类型元素的数组&#xff0c;可以看做是酒店中连续的6个房间. 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3…