【LabVIEW FPGA入门】流水线

LabVIEW中流水线

        在当今多核处理器和多线程应用程序的世界中,程序员在开发应用程序时需要不断思考如何最好地利用尖端 CPU 的强大功能。尽管用传统的基于文本的语言构建并行代码可能难以编程和可视化,但 NI LabVIEW 等图形开发环境越来越多地允许工程师和科学家缩短开发时间并快速实现他们的想法。

        由于 NI LabVIEW 本质上是并行的(基于数据流),因此多线程应用程序编程通常是一项非常简单的任务。框图上的独立任务自动并行执行,无需程序员进行额外的工作。但是那些不独立的代码片段又如何呢?在实现固有串行应用程序时,可以采取哪些措施来利用多核 CPU 的强大功能?

简介

        一种被广泛接受的用于提高串行软件任务性能的技术是流水线。简而言之,流水线是将串行任务划分为可以以流水线方式执行的具体阶段的过程。

        考虑以下示例:假设您正在自动化装配线上制造汽车。您的最终任务是建造一辆完整的汽车,但您可以将其分为三个具体阶段:建造框架、将零件放入其中(例如发动机)以及完成后对汽车进行喷漆。

        假设搭建框架、安装零件和喷漆各需要一小时。因此,如果一次只制造一辆车,每辆车将需要三个小时才能完成(参见下图 )。

        如何改进这个过程?如果我们设置一个用于框架构建的工作站,另一个用于零件安装的工作站,第三个用于喷漆的工作站,会怎么样?现在,当一辆车正在喷漆时,第二辆车可以安装零件,第三辆车可以进行框架施工。

 提高性能   

        尽管使用我们的新工艺,每辆汽车仍需要三个小时才能完成,但我们现在可以每小时生产一辆汽车,而不是每三个小时生产一辆——汽车制造工艺的吞吐量提高了 3 倍。请注意,此示例已出于演示目的进行了简化;有关管道的更多详细信息,请参阅下面的“重要问题”部分。

 LabVIEW中的基本流水线

        汽车示例中所展示的相同流水线概念可以应用于任何执行串行任务的 LabVIEW 应用程序。本质上,您可以使用 LabVIEW 移位寄存器和反馈节点将任何给定的程序制成“装配线”。以下概念图显示了示例管道应用程序如何在多个 CPU 内核上运行:

重要问题

        当使用流水线创建现实世界的多核应用程序时,程序员必须考虑几个重要的问题。具体来说,平衡流水线阶段和最小化内核之间的内存传输对于通过流水线实现性能提升至关重要。

平衡阶段

        在上面的汽车制造和 LabVIEW 示例中,假设每个管道阶段执行的时间相同;我们可以说这些示例管道阶段是平衡的。然而,在实际应用中,这种情况很少发生。考虑下图;如果阶段 1 的执行时间是阶段 2 的三倍,那么管道化这两个阶段只会产生最小的性能提升。

非流水线(总时间 = 4 秒):

 

流水线(总时间 = 3s):

注意:性能提升 = 1.33X(不是流水线的理想情况)

        为了纠正这种情况,程序员必须将任务从阶段 1 移至阶段 2,直到两个阶段的执行时间大致相等。对于大量的流水线阶段,这可能是一项艰巨的任务。

        在 LabVIEW 中,对每个流水线阶段进行基准测试有助于确保流水线良好平衡。使用平面序列结构结合 Tick Count (ms) 函数可以最轻松地完成此操作,如图  所示。

内核之间的数据传输

        最好尽可能避免在管道阶段之间传输大量数据。由于给定管道的各个阶段可以在单独的处理器内核上运行,因此各个阶段之间的任何数据传输实际上都可能导致物理处理器内核之间的内存传输。在两个处理器核心不共享高速缓存(或内存传输大小超过高速缓存大小)的情况下,最终应用程序用户可能会发现流水线效率下降。

FPGA中的流水线        

        流水线是一种可用于增强FPGA VI时钟速率和吞吐量的技术。在流水线设计中,用户可利用FPGA的并行处理特性提高顺序代码的有效性。如要实现流水线,必须将代码拆分为不同的级并连线每级的输入和输出端至循环中的反馈节点或移位寄存器。

        下图说明了如何将由 A 和 B 代码段组成的流程进行流水线化以减少每次循环迭代的长度。使用移位寄存器可以轻松实现将数据从一个循环迭代传递到下一个循环迭代(从 A 到 B)。

        可以利用流水线的一类应用程序是通过初步数据处理进行数据采集。在以下示例中,对数字输入线进行采样,测量数字信号中所有脉冲的宽度并将其写入 FIFO,以便在单独的循环中进行处理。在这两种实现中,移位寄存器用于存储数字线的状态和最后一个信号边沿的时间戳,以支持变化检测和连续信号边沿之间的时间计算。
 

         在顶部实现中(无流水线),循环继续计算脉冲宽度(减法),并在检测到边沿时将值写入 FIFO。

        在底层实现(使用流水线)中,当检测到信号边沿时,会将布尔标志写入附加移位寄存器,以便在下一个循环迭代中计算脉冲宽度并将其写入 FIFO。同时,从数字输入中获取下一个样本并与前一个样本进行比较。这使得底部循环能够检测边缘并并行处理它们并以更高的循环速率运行,从而使其能够检测更短的脉冲并在脉冲宽度测量中具有更好的定时分辨率。

        下文介绍了FPGA VI在单周期定时循环内的标准执行和流水线执行。

单周期定时循环中的标准执行

        在下列程序框图中,子VI A、B和C在单周期定时循环内顺序执行。因此,单周期定时循环的时钟速率必须设置为满足上述三个个运行子VI的运行时间的和值。

1378

单周期定时循环中的流水线执行,使用反馈节点

        在下列程序框图中,由于子VI的输入和输出连线至反馈节点,LabVIEW流水线处理子VI。在该FPGA VI中,子VI在单周期内并行执行,且最大时钟速率仅受具有最长组合路径的子VI的限制。

1378

单周期定时循环中的流水线执行,使用移位寄存器

        移位寄存器也可用于实现流水线代码,如下列程序框图所示。

1378

实现流水线代码

        实现流水线代码时考虑下列操作:

  • 最后一级的输出滞后输入的值等于流水线的级数。
  • 流水线填满前,时钟周期的输出无效。
  • 流水线的级数称为流水线深度。
  • 流水线延迟(以时钟周期为单位)对应其深度。流水线深度为N时,第N个时钟周期前的输出无效,且每个有效时钟周期的输出比输入端延迟N-1个时钟周期。

        请参考以下范例。

1378

        在该范例中,三个独立的执行步骤分别执行子VI A、B和C,即流水线深度为3。由于该代码需要三个执行步骤,输出要到时钟周期3才有效。每个有效时钟周期C的输出总是对应时钟周期C – (N – 1)的输入。

时钟周期说明
时钟周期 1在时钟周期1中,子VI A处理第一个测量值(Meas1),而子VI B和子VI C都处理移位寄存器的默认值(Default),产生无效输出。
时钟周期 2在时钟周期2中,子VI A处理第二个测量值(Meas2),子VI B处理时钟周期1中子VI A的输出,子VI C处理来自子VI B的无效输入,从而产生无效输出。
时钟周期 3在时钟周期3期间,由于所有输入都有效,并且子VI C的输出首次有效,流水线最终填满。子VI A处理第三次测量(Meas3),子VI B处理时钟周期2中子VI A的输出,而子VI C处理时钟周期2中子VI B的输出,从而产生与第一次测量(Meas1)相对应的输出。流水线填满后,全部后续时钟周期均生成有效的输出,常量延迟为两个时钟周期。

        提示考虑使用条件结构避免无效输出导致的未预期的操作,并确保控制算法在N个时钟周期后启用执行器。

使用流水线增加吞吐量

        使用流水线可增加吞吐量,因为流水线可在单周期定时循环内以更快的时钟域内运行。

1378

非流水线 (40 MHz)

        示意图顶部为非流水线循环的执行时间。该代码包含三个子VI,每个需要12.5 ns的传播延迟。子VI A至子VI C的全部延迟为37.5 ns,相对于40 MHz编译频率,延迟时间过长。

流水线 (40 MHz)

        示意图的中部给出了流水线处理代码将传播延时减少至12.5 ns,从而循环可在40 MHz进行编译。

流水线 (80 MHz)

        示意图底部为使用高达80 MHz时钟速率编译的循环,因为流水线循环的传播延迟仅为12.5 ns。

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

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

相关文章

【Docker】一文趣谈Docker

🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 文章目录 …

ELK日志管理实现的3种常见方法

ELK日志管理实现的3种常见方法 1. 日志收集方法 1.1 使用DaemonSet方式日志收集 通过将node节点的/var/log/pods目录挂载给以DaemonSet方式部署的logstash来读取容器日志,并将日志吐给kafka并分布写入Zookeeper数据库.再使用logstash将Zookeeper中的数据写入ES,并通过kibana…

第七节:Vben Admin权限-后端获取路由和菜单

系列文章目录 第一节:Vben Admin介绍和初次运行 第二节:Vben Admin 登录逻辑梳理和对接后端准备 第三节:Vben Admin登录对接后端login接口 第四节:Vben Admin登录对接后端getUserInfo接口 第五节:Vben Admin权限-前端控制方式 第六节:Vben Admin权限-后端控制方式 第七节…

PHP魔术方法详解

php魔术方法是一些特殊的方法&#xff0c;由特定的环境来进行触发。 这些魔术方法让开发者能够更好地控制对象的行为&#xff0c;特别是在处理不常见的操作或者需要自动化处理某些任务时非常有用。 1、_construct()构造函数&#xff1a; <?php highlight_file(__FILE__);…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:SideBarContainer)

提供侧边栏可以显示和隐藏的侧边栏容器&#xff0c;通过子组件定义侧边栏和内容区&#xff0c;第一个子组件表示侧边栏&#xff0c;第二个子组件表示内容区。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起…

《LeetCode热题100》笔记题解思路技巧优化_Part_4

《LeetCode热题100》笔记&题解&思路&技巧&优化_Part_4 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题二叉树&#x1f7e2;1. 二叉树的中序遍历&#x1f7e2;2.…

【计算机网络_应用层】https协议——加密和窃密的攻防

文章目录 1.https协议的介绍2. 加密和解密2.1 什么是加密2.2 常见的加密方式2.2.1 对称加密2.2.2 非对称加密 2.3 数据摘要&#xff08;数据指纹&#xff09;2.4 数字签名 3. https协议的加密和解密方案一&#xff1a;使用对称加密&#xff08;❌&#xff09;方案二&#xff1a…

Cesium模拟真实湖泊效果

1. 实现效果 2.实现方法 官方文档 Cesium的material中提供了水water的相关材质&#xff1a;传送门 详细代码&#xff1a; const getWater (data) > {// 根据几何实例创建贴地面图元waterPrimitive new Cesium.GroundPrimitive({geometryInstances: new Cesium.GeometryIn…

2024年腾讯云免费服务器申请入口,个人和企业均可申请

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费…

基于单片机的DDS函数信号发生器

单片机DDS函数信号发生器设计 该设计以AT89S52为主控芯片&#xff0c;通过控制高性能DDS&#xff08;直接数字频率合成&#xff09;芯片AD9834产生不同频率的信号&#xff0c;经过6阶巴特沃兹低通滤波电路&#xff0c;连接数字电位器的运算放大电路&#xff0c;输出信号。可以…

理解接口,

关键点 接口可抽象出重要的行为标准&#xff08;用抽象方法来表示&#xff09;。 可以把实现接口的类的对象的引用赋值给接口变量&#xff0c;体 现该类根据接口里的行为标准给出具体行为。 ~接口的思想~&#xff1a;可以要求某些类&#xff08;类的父类可不同&#xff09;有…

监视和内存观察

监视和内存观察 5.监视和内存观察5.1 监视5.2 内存 5.监视和内存观察 在调试的过程中我们&#xff0c;如果要观察代码执行过程中&#xff0c;上下文环境中的变量的值&#xff0c;有哪些方法呢&#xff1f; 这些观察的前提条件一定是开始调试后观察&#xff0c;比如&#xff1…

Python小白笔记

输入 # 一行输入多个数字&#xff0c;空格隔开&#xff0c;存入列表a中 a list(map(int, input().split())) print(a) >>>21 22 34 54 67 >>>[21, 22, 34, 54, 67] 输出 数据&#xff1a; print(%d%10.3f%(x,y)) y的精度为3&#xff0c;宽度为10 %0 …

Oracle 部署及基础使用

1. Oracle 简介 Oracle Database&#xff0c;又名 Oracle RDBMS&#xff0c;简称 Oracle Oracle系统&#xff0c;即是以Oracle关系数据库为数据存储和管理作为构架基础&#xff0c;构建出的数据库管理系统。是目前最流行的客户/服务器&#xff08;client/server&#xff09;或…

SpringTask实现的任务调度与XXL-job实现的分布式任务调度【XXL-Job工作原理】

目录 任务调度 分布式任务调度 分布式任务调度存在的问题以及解决方案 使用SpringTask实现单体服务的任务调度 XXL-job分布式任务调度系统工作原理 XXL-job系统组成 XXL-job工作原理 使用XXL-job实现分布式任务调度 配置调度中心XXL-job 登录调度中心创建执行器和任务 …

测试用例要如何写

1、测试点与测试用例 测试点不等于测试用例&#xff0c;这是我们首先需要认识到的。 问题1&#xff1a;这些测试点在内容上有重复&#xff0c;存在冗余。 问题2&#xff1a;一些测试点的测试输入不明确&#xff0c;不知道测试时要测试哪些。 问题3&#xff1a;总是在搭相似…

【pynput】监控是否打开百度贴吧网页

文章目录 简介Demo 简介 有网友提过一个要求&#xff0c;用 Python 实现一个 电脑打开某网站就自动关机的功能。 想到的思路有两个&#xff1a; 【windows 平台】, 获取活动的窗口标题&#xff0c;如果标题里包含了某些网站名称, 那就使用关机命令 可以定时拉取标题, 也可以使…

滑块验证码

1.这里针对滑块验证给了一个封装的组件verifition&#xff0c;使用直接可以调用 2.组件目录 3.每个文件的内容 3.1 Api文件中只有一个index.js文件&#xff0c;用来存放获取滑块和校验滑块结果的api import request from /router/axios//获取验证图片 export function reqGe…

Docker出现容器名称重复如何解决

假如你的重复容器名称是mysql5 删除已存在的容器&#xff1a;如果你不再需要那个已经存在的名为“mysql5”的容器&#xff0c;你可以删除它。使用下面的命令&#xff1a; docker rm -f mysql5这条命令会强制删除正在运行的容器。一旦容器被删除&#xff0c;你就可以重新使用这个…

Java 面向对象(类与对象 成员方法 方法重载 可变参数 构造方法 / 构造器 this关键字 包 访问修饰符)

目录 一、类与对象1. 类与对象的定义2. 类和对象的内存分配机制 二、成员方法1. 成员方法的定义2. 方法的调用机制3. 成员方法传参机制 三、方法重载四、可变参数1. 基本概念2. 基本语法3. 应用 五、 构造方法 / 构造器1. 特点2. 使用案例3. 对象创建的流程 六、this关键字1. 运…