Vitis HLS 学习笔记--HLS眼中的完美循环嵌套

2024-05-04 06:12

本文主要是介绍Vitis HLS 学习笔记--HLS眼中的完美循环嵌套,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1. 简介

2. 示例

2.1 不完美循环

2.2 完美循环

2.3 HLS 眼中的循环

3. 总结


1. 简介

在处理嵌套循环时(HDL或HLS工具中),优化循环结构对于实现最佳性能至关重要。嵌套循环的性能优化直接影响着计算的时延和资源利用率。创建完美嵌套的循环意味着循环结构被设计得紧凑、高效,以最大程度地利用硬件资源和并行计算能力。

在硬件描述或高级综合中,循环的每个细节都被转换为硬件电路或流水线阶段。因此,创建完美嵌套循环的目标是确保循环体内的计算被最有效地映射到硬件逻辑中,并且循环的边界和计算步骤都能够被静态分析和优化。这种优化可以带来多方面的好处,包括更低的时延、更高的时钟频率、更少的资源占用和更高的吞吐量。

通过创建完美嵌套的循环,可以确保最内层循环包含所有计算逻辑,并且循环之间没有逻辑依赖或数据依赖,从而允许并行执行和流水线处理。此外,循环边界应该是常量,以便编译器在优化时能够静态确定迭代次数,从而更好地利用硬件资源。最终,这些优化可以使得硬件实现具有更高的性能、更低的时延,并且能够更好地适应特定的应用需求。

以下介绍三种典型的循环及其特点。

完美循环嵌套:

  • 仅限最内层循环才包含循环主体内容。
  • 在循环语句之间不指定任何逻辑。
  • 所有循环边界均为常量。

半完美循环嵌套:

  • 仅限最内层循环才包含循环主体内容。
  • 在循环语句之间不指定任何逻辑。
  • 最外层的循环边界可采用变量。

非完美循环嵌套:

  • 内层循环具有变量边界。
  • 循环主体未完全包含在内层循环内。

2. 示例

2.1 不完美循环

void loop_imperfect(int A[20], int B[20]) {int i, j; // 定义循环变量i和jint acc;  // 定义累加器变量acc// 外层循环遍历数组B的每个元素for (i = 0; i < 20; i++) {acc = 0; // 在计算每个B[i]之前,将累加器归零// 内层循环遍历数组A,计算加权和for (j = 0; j < 20; j++) {acc += A[j] * j; // 将A[j]与其索引j相乘,并累加到acc}// 根据索引i的奇偶性决定B[i]的值if (i % 2 == 0)B[i] = acc / 20; // 如果i是偶数,B[i]为acc除以20的结果elseB[i] = 0; // 如果i是奇数,B[i]设为0}
}

如果按照纯软件代码的标准, 这段代码有很大的问题:

  • 内层循环对于每个B[i]都重新计算了加权和,即使B[i]被设为0。这意味着有一半的计算是不必要的。
  • 由于j的范围是固定的,所以acc的计算可以在循环外部进行一次,然后根据需要分配给B[i]。

但是在Vitis HLS的角度,以上两点都不是问题,因为代码最终对应的是硬件的连接。事实上,以上代码的问题是:循环主体未完全包含在内层循环内。

2.2 完美循环

void loop_perfect(int A[20], int B[20]) {int i, j; // 定义循环变量i和jint acc;  // 定义累加器变量acc// 外层循环遍历数组B的每个元素for (i = 0; i < 20; i++) {// 内层循环遍历数组A,计算加权和for (j = 0; j < 20; j++) {if (j == 0) acc = 0; // 当j为0时,累加变量归零acc += A[j] * j; // 将A[j]与其索引j相乘,并累加到acc// 当内层循环到达最后一个元素时,根据i的奇偶输出Bif (j == 19) {if (i % 2 == 0)B[i] = acc / 20; // 如果i是偶数,B[i]为acc除以20的结果elseB[i] = 0; B[i] = 0; // 如果i是奇数,B[i]设为0}}}
}

相对于2.1的“改进点”:

  • 累加器归零(if (j == 0) acc = 0;)的操作被移动到了内层循环的开始。
  • 条件判断(if (j == 19))被放置在内层循环的末尾。

如果按照纯软件代码的标准, 以上代码的问题更大了:

以上两个判断在每次内层循环时都会执行,这是不必要的,因为它只需要在内层循环开始或结束时执行一次!

2.3 HLS 眼中的循环

在 HLS 工具的眼中,完美循环嵌套是指循环结构被优化以便于硬件实现,从而实现最佳的性能和最低的资源使用。

原因如下:

  • 最内层循环包含所有计算:所有的计算逻辑都应该包含在最内层循环中,这样可以最大化并行性和流水线效率。
  • 循环边界是常量:这允许HLS工具在编译时确定循环的迭代次数,从而更好地优化生成的硬件。
  • 没有循环间的逻辑依赖:循环之间不应该有数据依赖或逻辑依赖,这样可以避免不必要的延迟,并允许循环独立地并行执行。
  • 循环展开和流水线:HLS工具可以自动展开循环并应用流水线技术,以提高并行性和吞吐量。
  • 数据访问模式是规则的:数据访问应该是可预测的,以便于HLS工具进行有效的内存访问优化。

因为 HLS 会用到如下两个优化指令:

#pragma HLS UNROLL // 指示HLS工具完全展开这个循环
#pragma HLS PIPELINE // 指示HLS工具流水线化这个循环

第一个指令,会让内层循环完全展开,即内层循环在一个周期内完成。

第二个指令,内层循环可流水线拆分,20个周期内完成。

所以,第二段代码实现了“最内层循环包含所有计算”,是HLS眼中的完美循环。

3. 总结

本文分享了处理嵌套循环时的重要性以及创建完美嵌套循环的关键原则。优化循环结构对于实现最佳性能至关重要,完美循环嵌套的设计能够最大程度地利用硬件资源和并行计算能力,从而提高性能并降低时延。

这篇关于Vitis HLS 学习笔记--HLS眼中的完美循环嵌套的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

Python循环结构全面解析

《Python循环结构全面解析》循环中的代码会执行特定的次数,或者是执行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都执行一次,这篇文章给大家介绍Python循环结构解析,感兴趣的朋友跟随... 目录for-in循环while循环循环控制语句break语句continue语句else子句嵌套的循

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Nginx部署React项目时重定向循环问题的解决方案

《Nginx部署React项目时重定向循环问题的解决方案》Nginx在处理React项目请求时出现重定向循环,通常是由于`try_files`配置错误或`root`路径配置不当导致的,本文给大家详细介... 目录问题原因1. try_files 配置错误2. root 路径错误解决方法1. 检查 try_f