为何循环展开结合重排对整数加法CPE无性能提升?
循环展开与重排对不同运算CPE的性能影响分析
关键观察
- 整数乘法、浮点加法、浮点乘法在展开+重排后性能明显提升(例如整数乘法CPE从3.01降至1.51);
- 整数加法CPE维持在1.01,接近1.00的延迟上限,无性能提升。
核心问题
- 为何整数加法无法从重排优化获益,而整数乘法、浮点加减乘可以?
- 重排理论上可借助多功能单元在运算延迟内并行执行操作,为何加减乘有此差异?是架构因素导致吗?
代码示例
void combine4(vec_ptr v, data_t *dest) { long i; long length = vec_length(v); data_t *d = get_vec_start(v); data_t t = IDENT; for (i = 0; i < length; i++) { t = t OP d[i]; } *dest = t; } void unroll2a_combine(vec_ptr v, data_t *dest) { long length = vec_length(v); long limit = length - 1; data_t *d = get_vec_start(v); data_t x = IDENT; long i; /* Combine 2 elements at a time */ for (i = 0; i < limit; i += 2) { x = (x OP d[i]) OP d[i + 1]; } /* Finish any remaining elements */ for (; i < length; i++) { x = x OP d[i]; } *dest = x; } void unroll2aa_combine(vec_ptr v, data_t *dest) { long length = vec_length(v); long limit = length - 1; data_t *d = get_vec_start(v); data_t x = IDENT; long i; /* Combine 2 elements at a time */ for (i = 0; i < limit; i += 2) { x = x OP (d[i] OP d[i + 1]); } /* Finish any remaining elements */ for (; i < length; i++) { x = x OP d[i]; } *dest = x; }
问题解答
整数加法无优化收益的本质原因
- 低延迟已达硬件吞吐量上限:多数CPU架构中整数加法的延迟仅为1周期,这意味着每周期就能完成一次加法运算,CPE已经接近理论上限1.00——此时流水线或多功能单元的并行能力无法带来额外收益,因为硬件已经在满负荷处理加法操作。
- 依赖链无法被有效拆解:即使做了重排优化,
x = x OP (d[i] OP d[i+1])的计算仍然依赖上一轮循环更新后的x值,无法完全拆分为无依赖的并行运算。对于延迟1周期的整数加法,这种依赖链的每一步都能在单周期内完成,重排无法压缩整体周期;而对于整数乘法、浮点运算这类延迟更高的操作(比如整数乘法延迟通常为3-4周期),重排后CPU可以在等待上一轮运算结果的间隙,利用多功能单元并行执行d[i] OP d[i+1]这类独立运算,从而打破依赖链的瓶颈,降低CPE。
内容的提问来源于stack exchange,提问作者Ayush Somani
相关产品推荐
相关产品推荐

