我这里有段自适应采样的简要代码:
@ti.kernel
def pathtrace():
for i, j in image_pixels:
diff = diff_pixels[i, j] # for self-adaptive sampling
if diff > NOISE_THRESHOLD:
sample(i, j)
对于并行此任务,随着 sample
执行次数增加,diff
逐渐减小。随着 kernel 调用次数越来越多,大多数子任务会提前结束掉,而 sample
是一个计算量非常大的函数。
这会造成线程发散吗?这种情况应该如何优化?能否增加一个前置 kernel 和一个 buffer,将 diff < NOISE_THRESHOLD
的 (i,j)
映射到 diff > NOISE_THRESHOLD
的 (i',j')
,这样就可以让这个kernel不需要 if
来决定是否 sample
。
- 但是这样的话可能会增加(随机)访存?
- 而且还要一个算法找到映射的方法,我想了一下这个是可以并行化的,而且计算复杂度应该比较小。
@ti.kernel
def build_map():
x, y = find_index(diff_pixels, i, j, NOISE_THRESHOLD)
# find_index 方法是适合并行的,它不一次性构建整个 map
# 而是随着 kernel 逐渐调用而修改 map
index_map[i, j] = (x, y)
@ti.kernel
def pathtrace():
for i, j in index_map:
x, y = index_map[i, j]
sample(x, y)