Vitis HLS 学习笔记--抽象并行编程模型-不良示例

目录

1. 简介

2. 基础 kernel

2.1 pass kernel

2.2 double_pass kernel

2.3 add_kernel

2.4 split kernel

3. 三种bypass

3.1 input_bypass

3.2 middle_bypass

3.3 output_bypass

4. 总结


1. 简介

本文展示三个在数据流水线中常见的问题:

  • 输入参数绕过了第一个函数,导致数据流水线性能下降。
  • 数据流内部的通道不是前馈的,绕过了任务,导致性能下降。
  • 数据流通道输出没有正确处理,导致性能下降。

2. 基础 kernel

首先引入四个通用 HLS kernel 函数作为后续演示的基础:

2.1 pass kernel

void pass(int a[128], int tmp1[128]) {
    for (int i = 0; i < 128; i++) {
        tmp1[i] = a[i];
    }
}

参数1 -> 参数2

2.2 double_pass kernel

void double_pass(int b[128], int tmp2[128], int tmp1[128], int tmp4[128]) {

    for (int i = 0; i < 128; i++) {
        tmp2[i] = b[i];
        tmp4[i] = tmp1[i];
    }
}

参数1 -> 参数2

参数3 -> 参数4

2.3 add_kernel

void add_kernel(int tmp1[128], int tmp2[128], int tmp3[128]) {

    for (int i = 0; i < 128; i++) {
        tmp3[i] = tmp1[i] + tmp2[i];
    }
}

参数1 + 参数2 -> 参数3

2.4 split kernel

void split(int a[128], int tmp1[128], int tmp2[128]) {

    for (int i = 0; i < 128; i++) {
        tmp1[i] = a[i];
        tmp2[i] = a[i];
    }
}

参数1 -> 参数2

参数1 -> 参数3

 

3. 三种bypass

3.1 input_bypass

void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOW

    int tmp1[128], tmp2[128], tmp4[128];

    pass(a, tmp1);
    double_pass(b, tmp2, tmp1, tmp4);
    add_kernel(tmp4, tmp2, tmp3);
}

优化后:

void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOW

    int tmp1[128], tmp2[128], tmp4[128];
    int tmp5[128];

    pass(a, b, tmp1, tmp2);
    Double_pass(tmp2, tmp1, tmp4, tmp5);
    add_kernel(tmp4, tmp5, tmp3);
}

对比: 

a -> tmp1 -> tmp4
                  + --> tmp3
     b    -> tmp2
a -> tmp1 -> tmp4
                  + --> tmp3
b -> tmp2 -> tmp5

3.2 middle_bypass

void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOW

    int tmp1[128], tmp2[128], tmp4[128];

    double_pass(a, b, tmp1, tmp2);
    pass(tmp2, tmp4);
    bypass(tmp1, tmp4, tmp3);
}

优化后:

void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOW

    int tmp1[128], tmp2[128], tmp4[128], tmp5[128];

    double_pass(a, b, tmp1, tmp2);
    pass(tmp2, tmp4, tmp1, tmp5);
    bypass(tmp5, tmp4, tmp3);
}

对比:

a -> tmp1 ------>
                  + --> tmp3
b -> tmp2 -> tmp4
a -> tmp1 -> tmp5
                  + --> tmp3
b -> tmp2 -> tmp4

3.3 output_bypass

void dut(int a[128], int b[128], int tmp2[128]) {
#pragma HLS DATAFLOW

    int tmp1[128], tmp3[128];

    split(a, tmp1, tmp2);
    pass(tmp1, b);
}

优化后: 

void dut(int a[128], int b[128], int tmp2[128]) {
#pragma HLS DATAFLOW

    int tmp1[128], tmp3[128];

    split(a, tmp1, tmp3);
    pass(tmp3, tmp2, tmp1, b);
}

 对比:

a -> tmp1 -> b
a -> tmp2
a -> tmp1 -> b
a -> tmp3 -> tmp2

4. 总结

本文展示了在数据流水线中常见的三个输入参数绕过问题及其解决方案。通过引入四个基础的HLS kernel函数:pass、double_pass、add_kernel和split,演示了input_bypass、middle_bypass和output_bypass三种问题的具体情形及优化后的解决方案。优化后的代码通过重新排列数据流通道,使得数据流遵循前馈路径,提高了性能。

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值