2017-05-15 12 views
0

아래 코드를 사용하여 동일한 입력에 대해 예기치 않은 차이가 있음을 발견했습니다. while 루프는 동일한 코드을 정확히 과 동일하게 사용하여 서로 다른 반복 량을 실행하는 경우가 있습니다. 나는 CPU와 GPU에 대해 동일한 문제를 스케줄링했다.동일한 입출력 버퍼를 가진 루프 내에서 ImageParam을 사용하면 예기치 않은 결과가 발생했습니다.

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

경쟁 조건이 있지만 실제로는 문제가 아닙니다. 입력 및 출력이 동일한 버퍼 인 경우 매우 다른 의미를 갖는 작은 흐림을 수행하고 있습니다. 제자리에서 흐리게 처리하려면 다른 종류의 알고리즘이 필요합니다.

do { 
    param.set(output1); 
    func_update.realize(output2); 
    param.set(output2); 
    func_update.realize(output1); 
    ... 
} while (count(0) > 0); 
+0

그것은 그림과 같이 실제로 나는 본질적으로 재귀 또 다른 알고리즘의 마지막 단계를 해결하기 위해 노력하고있어, 흐림 알고리즘 아니다 [여기] (HTTP : 한 가지 해결책은 이중 버퍼링이다 // stackoverflow.com/questions/42225879). 어쨌든 제안 해 주셔서 감사합니다. – pcn