vivado hls移除假性依赖关系以及改善循环流水线化说明

张开发
2026/4/11 11:39:25 15 分钟阅读

分享文章

vivado hls移除假性依赖关系以及改善循环流水线化说明
一、移除假性依赖和流水线化说明1.在vivado hls设计中如果要实现高效的pipeline流水线设计比较重要的一点是要对假性依赖和真性依赖进行甄别和判断如何对其进行正确的处理2.HLS工具作为一个高层次工具为了保证设计的正确性是不能过于冒进所以很多设计采取了保守的策略。这种保守是HLS编译器为了确保用户设计的逻辑的正确性。但是由于这种保守型的设计会将很多没有依赖关系的数据流或者操作看成了依赖关系会将一些假性的依赖进行了误判将假性依赖判断为真性依赖。这将会影响设计的流水线化由于存在依赖会造成II偏大从而降低了设计的throutput吞吐量3.吞吐量 (samples/s) 时钟频率 (Hz) / II可以看出II1是设计的目标4.II1表示每个clock都运行一个新的数据输入进来pipeline流水线就是实现II1的手段也就是说II是目标pipeline是手段和方式5.如果将假性依赖判断为真性依赖那么九影响设计的pipeline设计了所以设计中需要对真假依赖进行优化设计。二、依赖的几个概念1.真依赖 (True/Flow Dependency)后续操作必须等待前面操作的结果这是无法规避的。这种情况就是前后操作或者处理之间是有先后顺序的也就是操作是顺序执行的这个时候你就不能将依赖去掉否则你过度进行优化会造成逻辑错误。那么在这种情况下你将不能使用去依赖program指令进行指导HLS工具去优化你的设计了这个时候你唯一能做的是修改你的代码框架和结构或者改变代码的实现方式来改变这种依赖的等效关系从而来提高设计的性能。如果你没有办法改变这个真的依赖关系那么你就只能维持当前的设计了。2.假性依赖 (False Dependency)包括反依赖 (WAR) 和输出依赖 (WAW)。它们并非由数据流必需性引起而是由于存储位置变量被复用造成的可以消除。反依赖 (WAR) 和输出依赖 (WAW)是否能够移除也需要对代码进行分析和改写设计并不是说这两种模式下的设计全部可以去掉依赖而是说很多这种依赖模型下的依赖都是假的看起来是有依赖关系的实际上仔细想下是没有依赖关系的但是HLS工具没有那么智能化也不是说没有那么智能化吧主要还是太保守造成HLS工具睁一只眼闭一只眼不管这事儿直接当有依赖关系处理了。这个时候你就需要明确的告诉HLS编译器告诉它这个是没有依赖关系的你大胆的优化不要保守了。这个时候HLS工具就比较冒进的进行优化设计了。3.流水线中的依赖通常分为同一迭代内的依赖intra和跨迭代的依赖inter后者是流水线优化的主要障碍。关于同一迭代内的依赖就是同层for循环中前后两个操作存在依赖关系关于跨迭代的依赖inter就是for循环的第一次迭代和第二次迭代存在依赖关系第二次迭代和第三次迭代存在依赖关系。三、假性依赖出现的时机1.变量/数组复用 (Resource Reuse)在循环的不同迭代中重复使用同一个标量变量或数组的不同元素。编译器可能因无法精确分析索引而误判为同一个存储位置的竞争访问-2。2.静态变量 (Static Variables)static变量会跨迭代保持其值这天然构成了跨迭代的真依赖会阻止流水线启动。3.复杂或重叠的内存访问模式编译器难以静态证明的、复杂的指针或数组索引模式四、消除假性依赖的方法1.修改用户设计代码进行Code Refactoring代码重构代码重构的方式是从根本上解决假性依赖问题也是最推荐的方式。代码重构改进假性依赖的可行性操作有variable renaming也就是变量的重新命名变量重命名 (Variable Renaming)当循环中一个变量在不同阶段被赋予新值导致输出依赖 (WAW) 时可以为每次写操作引入新的临时变量消除复用拆分读写逻辑将复杂的读写操作拆解为更简单的步骤帮助编译器清晰地看到操作的独立性将静态变量改为局部变量用局部变量在循环内计算在循环外更新 static 变量将跨迭代依赖转化为一次性的外部更新指针受限 (Pointer Restriction)在C/C函数参数中使用 restrict 关键字向编译器保证指针所指向的内存区域是独立、不重叠的2.数组分割 (Array Partitioning)3.DEPENDENCE 编译指令 (The Last Resort)当前两种方法无效时可以使用 #pragma HLS DEPENDENCE 指令直接告诉编译器忽略某个假性依赖。但使用此方法需要谨慎因为错误地忽略真依赖会导致硬件功能错误-。指令格式#pragma HLS DEPENDENCE variablevar inter/intra RAW/WAR/WAW true/false参数说明variable指定存在依赖的变量名。inter / intrainter 指循环不同迭代间的依赖intra 指同一迭代内的依赖。RAW / WAR / WAW可选参数精确指定要忽略的依赖类型。true / falsetrue 表示强制工具考虑依赖false 表示移除忽略该假性依赖。

更多文章