仅对英特尔可见 — GUID: hpg1574195439908
Ixiasoft
仅对英特尔可见 — GUID: hpg1574195439908
Ixiasoft
4.4.3.2. 存储器访问合并和加载-存储单元
Intel® HLS Compiler可能会将多个存储器访问合并为一个更宽的存储器访问,以节省实例化LSU的个数。
当编译器合并存储器访问时,被称为static coalescing,因为合并发生在编译时。这种静态合并与dynamic coalescing由突发合并LSU完成。
当编译器检测到多个存储器操作访问存储器中的连续位置时,通常会尝试静态合并。这种合并通常会有益处,因为它减少了争夺共享存储器接口的LSU个数。
编译器合并的存储器访问最高达到已访问存储器接口的宽度。对于外部存储器接口,最大宽度由您正在访问的外部存储器属性预先确定。对于组件(内部)存储器接口,编译器可以根据编译器创建的存储器几何结构设置最大宽度。有关组件存储器的更多详细信息,请参阅组件存储器(存储器属性)。
对于以下代码实例, Intel® HLS Compiler将4字节宽的加载操作静态合并为一个16字节宽的加载操作。对四个存储操作也进行了类似的合并。合并加载和存储操作可将对Avalon MM Host接口所需的访问次数减少到4次。
#include "HLS/hls.h"
component void
static_coalescing(ihc::mm_host<int, ihc::dwidth<128>, ihc::awidth<32>,
ihc::aspace<1>, ihc::latency<0>> &in,
ihc::mm_host<int, ihc::dwidth<128>, ihc::awidth<32>,
ihc::aspace<2>, ihc::latency<0>> &out,
int i) {
// Four loads statically coalesced into one 16 bytes wide load
int a1 = in[3 * i + 0];
int a2 = in[3 * i + 1];
int a3 = in[3 * i + 2];
int a4 = in[3 * i + 3];
// Four stores statically coalesced into one 16 bytes wide store
out[3 * i + 0] = a4;
out[3 * i + 1] = a3;
out[3 * i + 2] = a2;
out[3 * i + 3] = a1;
}

component int alignedRead(AHost &A, unsigned int i) { hls_register int memory_line[PARALLEL_WORDS] = {}; int word_base = PARALLEL_WORDS * (i / PARALLEL_WORDS); #pragma unroll for (int j = 0; j < PARALLEL_WORDS; j++) { int idx_base = PARALLEL_WORDS * ((i + j) / PARALLEL_WORDS); bool doesntWrap = idx_base == word_base; if (doesntWrap) { memory_line[j] = A[i + j]; } } ... }
编译器推断出一个非对齐LSU,因为编译器无法确定j的所有值都是从存储器A的相同字读取而来。即使j的范围恰好好与存储器的一个字匹配,该访问仍然可能会换行到另一个字。可能需要多次读取。如果您以字宽对齐为基础编写访问的代码,则编译器可以保证不会发生换行,从而编译器会为您提供对齐的LSU。