Page 84 - 《软件学报》2024年第6期
P. 84
2660 软件学报 2024 年第 35 卷第 6 期
1. cur_region=region.
2. max_block_len=0; step_len= block_len/2.
3. 调用算法 2 更新 cur_region, 转 Step 4.
4. 根据公式 (1) 和公式 (3) 计算 cur_region 的 Space.
5. 根据公式 (2) 判断 Space 是否小于 buf_size, 否则转 Step 9.
6. 判断 block_len 是否大于 max_block_len, 否则结束.
7. 如果 has_newregion_flag=1, 则 cur_region=region.
8. max_block_len=block_len, block_len=block_len+step_len, step_len=step_len/2, 转 Step 3.
9. 如果 has_newregion_flag=1, 则 region=cur_region.
10. block_len=block_len–step_len, step_len=step_len/2, 转 Step 3.
算法 2. update_region.
Space: (128–0+64)×4+64×4=1280.
输入: block_len 和 region 信息;
输出: region 信息和 region 是否被更新的标志 has_newregion_flag.
1. 初始化 has_newregion_flag=0.
2. 遍历所有 region 直到所有 region 都被处理过.
2.1. 依次遍历当前 region 的所有访问偏移 S i , 若存在 i, 使得 S i +1–S 0 >block_len, 新增一个 region, 将 S i +1 到 S n 对应
的数组访问划分进新 region, 并记 has_newregion_flag=1; 否则, continue.
3. 返回 has_newregion_flag.
以图 11 中的代码作为优化方案求解示例, 该例中共有 a 数组的 4 个访问 a[i]、a[i+1]、a[i+2] 和 a[i+128], 编
译器分析将得到数组 a 的 4 个访问的 offset 分别为 0、1、2、128, 数组 b 的 offset 为 0.
#pragma ccc sbuf mem2ldm(a,b) ldm_addr(buf) ldm_size(1024)
for(i = 0; i < 10240; i++)
{
a[i] = (a[i+1] + a[i+2]) / 2;
x = a[i] / a[i+128]+b[i];
… //其他代码
}
图 11 编译指示代码段示例
实际求解过程如下.
Step 1. 初始化分块大小 block_len=1024/8=128.
Step 2. 初始化 region1={a[i]、a[i+1]、a[i+2]、a[i+128]}; region2={b[i]}.
Step 3. 计算 Space: (128–0+128)×4+128×4=1536.
Step 4. Space=1536>1024.
Step 5. 调用算法 2 返回 0, region 不变.
Step 6. block_len=128/2=64.
Step 7. 计算
Step 8. Space=1280>1024.
Step 9. 调用算法 3 返回 1, region 变为: region1={a[i]、a[i+1]、a[i+2]}, region2={b[i] }, region3={a[i+128]}.
Step 10. 计算 Space: (2–0+64)×4+64×4+64×4=776.
Step 11. Space=776<1024, 终止.
基于上述计算过程可得到编译优化参数:
block_len=64, 3 个 region: region1={a[i]、a[i+1]、a[i+2]}, region2={b[i]}, region3={a[i+128]}.