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)。