Intel® FPGA SDK for OpenCL™ Pro Edition: 最佳实践实践指南

ID 683521
日期 9/26/2022
Public
文档目录

4.1.3. 优化通道或管道的缓冲推断

除了手动添加缓冲通道或管道之外, Intel® FPGA SDK for OpenCL™ Offline Compiler通过尽可能调整缓冲区的大小来提高内核的吞吐量。

在编译期间,离线编译器计算交互通道或管道之间的调度失配。这些不匹配可能会导致读和写操作之间的不平衡。离线编译器自动执行缓冲区推断优化以纠正不平衡。

请参考如下实例:

表 16.  通道和管道的缓冲区推断优化
带有通道的内核 带有管道的内核
__kernel void producer ( __global const uint * restrict src, const uint iterations) { for(int i = 0; i < iteration; i++) { write_channel_intel(c0,src[2*i]); write_channel_intel(c1,src[2*i+1]); } } __kernel void consumer ( __global uint * restrict dst, const uint iterations) { for(int i = 0; i < iterations; i++) { dst[2*i] = read_channel_intel(c0); dst[2*i+1] = read_channel_intel(c1); } }
__kernel void producer ( __global const uint * restrict src, const uint iterations, write_only pipe uint __attribute__((blocking)) c0, write_only pipe uint __attribute__((blocking)) c1) { for(int i = 0; i < iteration; i++) { write_pipe(c0,&src[2*i]); write_pipe(c1,&src[2*i+1]); } } __kernel void consumer ( __global uint * restrict dst, const uint iterations, read_only pipe uint __attribute__((blocking)) c0, read_only pipe uint __attribute__((blocking)) c1) { for(int i = 0; i < iterations; i++) { read_pipe(c0,&dst[2*i]); read_pipe(c1,&dst[2*i+1]); } }

如果内核之间的通道或管道不能形成循环,则离线编译器执行缓冲区推断优化。内核之间的cycle(循环)是源自内核的路径,通过写入通道或者写入管道调用,并返回原始内核。该实例中,假设内核producer中的写入通道或者写入管道调用调度间隔10个周期,但是读通道或读管道调用调度间隔15个周期。由于在对c1的读操作之前,可能会发生5次额外的写操作,导致对c1的读和写操作中存在临时不匹配。为了纠正这种不平衡,离线编译器将5个周期的缓冲区大小分配给c1以避免停顿。该额外的缓冲区容量将producer内核中c1写操作和consumer内核中的c1读操作解耦(decouple)。