函数例化是一种最优化技巧,不仅具有维持函数层级的面积优势,还可提供另一个强大的选项:在函数的特定实例上执行针对性局部最优化。这样可以简化围绕函数调用的控制逻辑,也可能改进时延和吞吐量。
鉴于调用函数时,函数的部分输入可能是常量,FUNCTION_INSTANTIATE 编译指示或指令可藉此简化周围控制结构,并生成进一步最优化的、更小的函数块。这可通过示例来细化解释。
给定如下代码:
char foo(char inval, char incr) {
#pragma HLS INLINE OFF
#pragma HLS FUNCTION_INSTANTIATE variable=incr
return inval + incr;
}
void top(char inval1, char inval2, char inval3,
char *outval1, char *outval2, char *outval3)
{
*outval1 = foo(inval1, 0);
*outval2 = foo(inval2, 1);
*outval3 = foo(inval3, 100);
}
很明显,函数 foo
已写为执行三次互斥运算(根据 incr
的值)。函数 foo
的每个实例都是以相同方式实现的。虽说这对于函数复用和面积最优化很实用,但也意味着函数内部的控制逻辑必须更为复杂,才能容纳两次互斥运算。
FUNCTION_INSTANTIATE 最优化允许对每个实例进行独立最优化,从而减少功能和面积。完成 FUNCTION_INSTANTIATE 最优化后,以上代码可有效转换为 2 个独立函数,每个函数都针对模式的不同可能值来完成最优化,如下所示:
void foo1() {
// code segment 1
}
void foo2() {
// code segment 2
}
如果在未经大幅内联或代码修改的情况下,在不同层级使用该函数而导致函数难以共享,那么函数例化可提供改进面积的最佳方法:大量小型局部最优化的副本比大量无法共享的大型副本更有效。