使用下面的代码,我注意到同一输入有一些意想不到的差异。有时,while循环执行不同的迭代次数,即使使用相同的代码和输入数据也是如此。我在调试CPU和GPU时遇到了同样的问题。
int main() {
int dx, dy;
Buffer<uint8_t> output;
Buffer<int> count = Buffer<int>::make_scalar();
ImageParam param(UInt(8), 2);
update_func = build_hysteresis_update(param);
count_func = build_hysteresis_count(param);
output = ini_func.realize(dx, dy); // ini_func always returns the same output.
do {
param.set(output);
update_func.realize(output); // --> same input/output. I use this way because performance get really better.
param.set(output);
count_func.realize(count);
} while (count(0) > 0); // --> Different quantities of iterations happens here.
}
Func build_hysteresis_update(ImageParam input) {
RDom rh(-1, 3, -1, 3);
Func inb, update;
Var x, y;
inb = BoundaryConditions::repeat_edge(input);
update(x, y) = cast<uint8_t>(select(inb(x, y) == 1 && sum(cast<uint16_t>(inb(x+rh.x, y+rh.y))) > 9, 254, inb(x, y) == 254, 255, inb(x, y)));
Var xi, yi;
update.tile(x, y, xi, yi, 32, 8).parallel(y).vectorize(xi, 8);
return update;
}
Func build_hysteresis_count(ImageParam input) {
RDom rc(0, input.width(), 0, input.height());
Func count;
count() = sum(select(input(rc.x, rc.y) == 254, 1, 0));
return count;
}
我尝试过这些解决方案,但是性能不是很好。有没有更好的方法来避免这个问题(这似乎是一个竞争条件问题)保持第一个表现?我也试图使用“device_sync”而没有成功解决问题。
// Solution 1:
Func build_hysteresis_update(ImageParam input) {
...
// Adding "aux" and replace "inb" inside "update" func.
aux(x, y) = inb(x, y);
update(x, y) = cast<uint8_t>(select(aux(x, y) == 1 && sum(cast<uint16_t>(aux(x+rh.x, y+rh.y))) > 9, 254, aux(x, y) == 254, 255, aux(x, y)));
...
// Also adding scheduling "compute_root" for "aux" func.
aux.compute_root();
...
}
// Solution 2:
int main() {
...
do {
// Don't pass the allocated "output" to the "realize" method.
param.set(output);
output = func_update.realize(dx, dy);
...
} while (count(0) > 0);
...
}
答案 0 :(得分:0)
虽然存在竞争条件,但这不是真正的问题。您正在做一个小模糊,如果输入和输出是相同的缓冲区,则具有非常不同的含义。模糊就地需要不同类型的算法。一种解决方案是双缓冲:
do {
param.set(output1);
func_update.realize(output2);
param.set(output2);
func_update.realize(output1);
...
} while (count(0) > 0);