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

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

8.5. 通过控制存储器赋值因子来优化对局部存储器的访问

存储器复制因子是您的设计中用于实现局部存储器系统的M20K存储器模块的数量。 要控制存储器复制因子,请使用OpenCL™内核中的max_replicates内核属性。

Intel® 的M20K存储器模块有两个physical(物理)端口。每个M20K块中的可用logical(逻辑)端口数量取决于泵(pumping)的程度。Pumping是相对于设计的其余部分对M20K块时钟频率的一种度量。

考虑以下代码实例,其中singlepump属性应用于局部存储器系统,lmem,它具有3个读访问和一个写访问。singlepump属性指示M20K块以与设计其余部分相同的频率运行。

__kernel void three_copies(int raddr, int waddr) {
    int __attribute__((memory,
                       numbanks(1),
                       singlepump,
                       max_replicates(3)))
                       lmem[16];

    lmem[waddr] = lmem[raddr] + lmem[raddr + 1] + lmem[raddr + 2];
    // do something with lmem
}
图 85. 访问Single-Pumped(单泵)M20K存储器模块
编译器创建无仲裁网络,如访问Single-Pumped(单泵)M20K存储器模块中所示。每个单泵M20K块有两个可用的逻辑端口。局部存储器系统中的每个写端口必须连接到所有您设计用于实现存储器系统的M20K块。局部存储器系统中的每个读端口必须连接到一个M20K块。由于这些连接限制,必须有三个M20K块才能实现lmem中指定数量的端口。
注: 如果您将max_replicates(3)更改为 max_replicates(1),您会观察到一个M20K块在三个读取之间进行仲裁。

如果在局部变量声明中包含doublepump内核属性,则指定M20K存储器模块的运行频率是设计中其余部分的两倍。

__kernel void three_copies(int raddr, int waddr) {
    int __attribute__((memory,
                       numbanks(1),
                       doublepump))
                       lmem[16];

    lmem[waddr] = lmem[raddr] + lmem[raddr + 1] + lmem[raddr + 2];
    // do something with lmem
}
图 86. 访问Double-Pumped(双泵)M20K存储器模块

每个double-pumped(双泵)M20K块有四个可用的逻辑端口。因此,只需要一个M20K块即可实现lmem中的三个读端口和一个写端口。

注意:
  • 双泵存储器会增加资源开销。只有在doublepump内核属性能够实际节省M20K和/或提高性能时,才使用该内核属性。
  • Store(仓库)必须连接到每个复制。因此,如果store超过三个,则不会复制存储器。局部存储器复制适用于单个store。
  • 由于复制了整个存储器系统,您可能会观察到潜在的大型M20K存储器模块。