使用卤化物进行优化

时间:2017-01-09 20:49:02

标签: halide

我正在使用Halide来优化模板计算,但调度部分是一种挑战!这是我的Halide代码,我正在使用AOT编译:

//Halide declarations:
Param<int> max_x, max_y, max_z; 
Param<float> r; 
Var x("x"), y("y"), z("z"), s, xi("xi"), yi("yi"), m("n"), xo("xo"), yo("yo"), index("idx");
Func f1_unbound("f_ub"), f1_bound("f_b"), result("res");

ImageParam input1(type_of<float>(), 3);
ImageParam input2(type_of<float>(), 3);

Expr t_h;

//The algorithm:
t_h = input2(x, y, z) / (r * input1(x, y, z));
f1_unbound(x, y, z) = 100.0f / (t_h) * pow((t_h / 200.0f), 1.5f); 
f1_bound(x, y, z) =  BoundaryConditions::repeat_edge(f1_unbound, 1, max_x - 2, 1, max_y - 2, 1, max_z - 2)(x, y, z);
result(x, y, z) = 0.125f * (f1_bound(x, y, z) + f1_bound(x + 1, y, z) +
                            f1_bound(x, y + 1, z) + f1_bound(x + 1, y + 1, z) + 
                            f1_bound(x, y, z + 1) + f1_bound(x + 1, y, z + 1) +
                            f1_bound(x, y + 1, z + 1) + f1_bound(x + 1, y + 1, z + 1));

f1_bound.split(x, x, xi, 32).unroll(y, 2).unroll(xi, 2).vectorize(xi, 16).compute_at(result, y).store_at(result, y);
//f1_unbound.compute_root();
//f1_bound.vectorize(x, 16);
result.tile(x, y, x, y, xi, yi, 32, 8).vectorize(xi, 16).bound(x, 0, ((max_x + 1) / 2) * 2).bound(y, 0, ((max_y + 1) / 2) * 2).bound(z, 0, (max_z + 1)).parallel(y);
result.print_loop_nest();

result.compile_to_static_library("v_halide", {input1, input2, r, max_x, max_y, max_z}, "v_halide");
std::cout << "Compiled to static library!" << std::endl;

我理解在分割/平铺和指定每个函数的评估位置时,如果使用不同的计划,性能会如何变化。但是,我在并行性能方面存在一些问题。我尝试了不同的并行化调度,例如上面的那个。然而,我无法找到有效的并行计划,并且分析数字在某种程度上令人困惑。对于上述计划,随着线程数量的增加,“结果”变得更慢,f1_bound变得更快,而报告为线程的数字(如果我没有记错,则是每个区域中活动线程的平均数量)正在增加:

  

4个主题:
  使用的平均线程数:3.586322

     

堆分配:19500峰值堆使用量:116640字节

     

res:0.946ms(33%)个主题:3.119

     

f1_b:1.873ms(66%)线程:3.823峰值:116640数量:19500平均值:29160

     

2个帖子:   使用的平均线程数:1.934264

     

堆分配:19500峰值堆使用量:58320字节

     

res:0.769ms(19%)线程:1.794

     

f1_b:3.152ms(80%)线程:1.968峰值:58320数量:19500平均值:29160

当我计划f1_bound和unbound时,我会更好地扩展,因为我增加了线程数,但我认为局部性较少,因此单个线程的代码比没有并行化的代码慢。

f1_bound.split(x, x, xi, 32).unroll(y, 2).unroll(xi, 2).vectorize(xi, 16).compute_at(result, y);
f1_unbound.split(x, x, xi, 32).unroll(y, 2).unroll(xi, 2).vectorize(xi, 16).compute_at(result, y).store_at(result, y);

有关更好的时间表的任何建议吗?

0 个答案:

没有答案