【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。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记 | 微信小程序项目day02

今日学习内容 安装uni-ui跟uni-helper/uni-ui-types配置pinia持久化请求工具类的拦截器请求工具类的请求函数 安装uni-ui跟uni-helper/uni-ui-types npm install -g cnpm --registryhttps://registry.npmmirror.com npm set registry https://registry.npmmirror.com npm i …

电脑充电器能充手机吗?如何给手机充电?

电脑充电器可以给手机充电吗? 电脑充电器可以给手机充电,但前提是电脑充电器的功率输出与手机的功率匹配且接口匹配。 假设电脑充电器的输出功率为5V/2A,手机也支持5V/2A的输入功率。 只要接口匹配,就可以使用电脑充电器给手机充…

2024智慧农场系统微信小程序前端如何上传以及配置

2024智慧农场系统微信小程序前端如何上传以及配置 首先下载微信开发者工具 下载好以后打开,然后导入项目 前端修改:siteinfo.js 里面的域名信息 改完之后开始在微信开发者工具中开发工具中编译、上传、发布即可

vim | 介绍vim以及配置vimrc文件

好像熟练使用vim 是玩linux 必修课 当然,初代玩家能在vim 完成编辑 并保存已是入门了,想当初在大学的时候,死活转不过来,玩不过来,甚至有些恐惧 但后来,弄清楚原理,反倒觉得简简单单已是完美了。…

19. UE5 RPG使用GameplayEffect的Attribute Based Modifiers

前几篇文章我也说了GE的基础使用,但是,对一些属性的应用没有述说,后续,我将一点一点的将它们如何使用书写下来。 这一篇,主要就讲解一下Attribute Based Modifiers使用,先说一下它的应用场景,一…

C++ -- 多态

多态 1. 多态的概念 多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 2. 多态的定义及实现 2.1多态的构成条件 多态是在不同继承关系的类对象,去调用同一函…

实现界面跳转及注册界面编写(AndroidStudio)

目录 一、代码 二、最后效果 一、代码 1.先新建一个activity文件 2.注册界面的代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:la…

Docker学习之数据管理(超详解析)

Docker存储资源类型&#xff1a; 用户在使用 Docker 的过程中&#xff0c;势必需要查看容器内应用产生的数据&#xff0c;或者需要将容器内数据进行备份&#xff0c;甚至多个容器之间进行数据共享&#xff0c;这必然会涉及到容器的数据管理&#xff1a; &#xff08;1&#xff…

Java代码基础算法练习-判断素数-2024.03.17

任务描述&#xff1a; 输入一个数x&#xff0c;判断它是否是素数。 提示&#xff1a;素数是只能被1和它本身整除的数&#xff0c;1不是素数。 任务要求&#xff1a; 代码示例&#xff1a; package march0317_0331;import java.util.Scanner;public class March0317 {public …

LeetCode 面试经典150题 55.跳跃游戏

题目&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 思路…

django实现api接口

&#xff08;前期准备&#xff09;第一步&#xff1a;虚拟环境 在windows上使用virtualenvwrapper。 pip install virtualenvwrapper-win 接着&#xff0c;添加环境变量。 echo %WORKON_HOME% 接下来就是创建虚拟环境&#xff0c;假如创建myenv mkvirtualenv myenv 进入…

RabbitMQ——死信队列和延迟队列

文章目录 RabbitMQ——死信队列和延迟队列1、死信队列2、基于插件的延迟队列2.1、安装延迟队列插件2.2、代码实例 RabbitMQ——死信队列和延迟队列 1、死信队列 死信队列&#xff08;Dead Letter Queue&#xff0c;DLQ&#xff09;是 RabbitMQ 中的一种重要特性&#xff0c;用…

ChatGPT编程实现简易聊天工具

ChatGPT编程实现简易聊天工具 今天借助[[小蜜蜂]][https://zglg.work]网站的ChatGPT练习socket编程&#xff0c;实现一个简易聊天工具软件。 环境&#xff1a;Pycharm 2021 系统&#xff1a;Mac OS 向ChatGPT输入如下内容&#xff1a; ChatGPT收到后&#xff0c;根据返回结…

企业内部培训考试系统培训计划功能说明

培训计划是预设好的一套课程系列&#xff0c;包含课程和考试&#xff0c;分多个阶段&#xff0c;每完成一个阶段就会在学习地图上留下标记&#xff0c;让用户看到自己的努力成果&#xff0c;增强成就感&#xff0c;从而坚持完成课程。 企业内部培训考试系统中如何设置培训计划…

动态代理原理- JDK动态代理、CGLIB动态代理

概述&#xff1a;在不改变原有功能代码的前提下&#xff0c;能动态的实现方法的增强 JDK动态代理原理&#xff1a; 通过实现接口&#xff0c;获取到接口里面的所有方法通过Proxy创建代理实例通过反射机制&#xff0c;获取到一个一个的方法对象调用InvocationHandler接口中的in…

Python之Web开发中级教程----ubuntu中下载安装Postman

Python之Web开发中级教程----ubuntu中下载安装Postman PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 查看ubuntu系统中是否已经安装了…

Java BIO (同步阻塞型IO) 内容上集

IO简介 一、前言 在java软件设计开发中&#xff0c;通信框架是不可避免的&#xff0c;我们在不同的系统或者这不同的进程之间进行数据交互&#xff0c;或者在高并发的场景下需要用到网络通信相关的技术&#xff0c;从上节课的例子当中我们看出同步阻塞式的IO通信(BIO)效率过于…

【计算机网络】基本概念

基本概念 IP 地址端口号协议协议分层封装分用客户端服务器请求和响应两台主机之间的网络通信流程 IP 地址 概念&#xff1a;IP 地址主要是用于唯一标识网络主机、其他网络设备&#xff08;如路由器&#xff09;的网络地址。简单来说&#xff0c;IP地址用来唯一定位主机。格式&…

cartographer学习与使用

记录一下在配置和使用cartographer建图时遇到的各种问题吧。 我的数据 配置文件&#xff1a; my_rslidar.launch <launch> <param name"/use_sim_time" value"false" /> <!--启动建图节点--> <node name"cartographer_n…

【JACS】:用于稳定单原子分散的催化剂架构可对吸附到 Pt 原子、氧化 Pt 簇和 TiO2上金属 Pt 簇的 CO 进行特定位点光谱和反应性测量

摘要&#xff1a;氧化物负载的贵金属纳米粒子是广泛使用的工业催化剂。由于费用和稀有性&#xff0c;开发降低贵金属纳米颗粒尺寸并稳定分散物质的合成方案至关重要。负载型原子分散的单贵金属原子代表了最有效的金属利用几何结构&#xff0c;尽管由于合成均匀且稳定的单原子分…