ZHCUAU3J January 2018 – March 2024
每个流地址生成器 (SA) 都有一个隐式谓词,该谓词是在存储到内存时根据有效矢量元素的数量进行设置的。然而,无法使用 C 语义表达这种行为,原因是编译器不能发现或跟踪硬件如何或何时进行断言,因为预测断言基于 SA 配置产生,并且可能因每次调用存储时而有所不同。
为了在 C 中表达此功能,编译器提供了一个可供利用的显式语义框架。该框架使用从相应 SA 中提取的谓词值显式地断言存储操作。如果编译器检测到提取的谓词类型与 SA 访问器(以及相应的存储器操作)匹配,则编译器尝试将自己折叠起来以便利用 SA 的隐式断言功能。
将谓词值提取为 __vpred
类型值的 API 包括以下内容:
__SA0_VPRED(type)
__SA1_VPRED(type)
__SA2_VPRED(type)
__SA3_VPRED(type)
下述是这种用法的一个示例:
__SA0_OPEN(params);
for (I = 0; I < ((ROW * COL) / SIMD); I++)
{
vpred sa0_vp = __SA0_VPRED(int16); // EXTRACT SA0 PREDICATE
int16 *addr = __SA0ADV(int16, (int16 *)data); // EXTRACT SA0 ADDRESS
__vstore_pred(sa0_vp, addr, data); // USE PREDICATED INTRINSIC
}
__SA0_CLOSE();
如此示例中所示,与特定流地址生成器关联的矢量谓词的提取必须在调用存储内在函数之外进行。如果不是这种情况,根据 C 规则,调用参数的评估顺序将是不明的。因此,执行以下语句:
__vstore_pred(__SA0_VPRED(int16), __SA0ADV(int16, (int16 *)data);
会导致未定义的行为,因为 SA0ADV 修改了 SA0_VPRED() 返回的值。
无论在谓词提取 API 或 SA 访问中使用哪种类型,SA 推进量将始终根据其预配置的状态进行递增。给定的类型名并不影响如何进行 SA 推进。