다음과 같은 문제가 있습니다. 동적로드 예약 방식을 사용하여 this paper에 기반한 병렬 사전 필터를 생성했습니다. 불행히도 직렬 필터가 표시하지 않는 유물이 발생하여 스레드에서 동기화 문제가 있다는 것을 암시하는 임의의 위치에 나타납니다. 그러나 나는 그것이 어디에 있는지 알 수 없다. 나는 지금까지 비슷한 문제를 보여주지 않았지만 지금은 그렇습니다. 매우 유사한 그레이 스케일 필터를 가지고 있습니다.동적로드 스케줄링을 사용하는 병렬 이미지 컨볼 루션 필터 : 아티팩트
왼쪽 그림은 원하는 결과 순차 알고리즘 달성 올바른 하단에 상기 아티팩트를 도시한다.
추가 테스트를 통해 이제는 스레드가 이미지의 특정 부분을 필터링하지 않고 건너 뜁니다. 나는 계속 조사 할 것이다.
내 코드의 구조는 다음과 같습니다. ParallelPrewittFilter는 ParallelSobelianFilter에서 상속을 받고 올바른 종류의 작업자, 즉 다음 인스턴스 (실행 가능한 인터페이스를 구현하는 클래스)를 만드는 팩터 리 메서드 만 구현합니다. PrewittFilterWorker는 SobelianFilterWorker (ParallelFilterWorker에서 상속)에서 상속 받아 회선 커널을 반환하는 메서드 만 구현합니다. 그래서 ParallelSobelianFilter와 SobelianFilter worker로부터 관련 코드를 게시 할 것입니다. 마지막 코드 블록은로드 일정 코드입니다.
ParallelSobelianFilter :
public BufferedImage applyFilter(BufferedImage image) {
//taking the red and alpha channels from image and placing them
//in the arrays red[width*height] and alpha[width*height]
ParallelFilterWorker.resetDynamicLoadCounter();
for (SobelianFilterWorker worker : workers) {
worker.setSourceArrays(width, height, alpha, red, green, blue, hasAlpha);
worker.setDestImage(result);
}
for (Thread thread : threads) {
System.out.println("starting thread ");
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
}
SobelianFilterWorker :
:protected void filterPixel(int index) {
//[..]
if (x < 1 || y < 1 || x > width - 2 || y > height - 2) {
//do nothing
color = red[index];
} else {
firstPass = red[index - 1] * kernel[0][1] + red[index + 1] * kernel[2][1]
+ red[index - width - 1] * kernel[0][0] + red[index - width] * kernel[1][0]
+ red[index - width + 1] * kernel[2][0] + red[index + width - 1] * kernel[0][2]
+ red[index + width] * kernel[1][2] + red[index + width + 1] * kernel[2][2];
//transposed kernel
secondPass = red[index - 1] * kernel[1][0] + red[index + 1] * kernel[1][2]
+ red[index - width - 1] * kernel[0][0] + red[index - width] * kernel[0][1]
+ red[index - width + 1] * kernel[0][2] + red[index + width - 1] * kernel[2][0]
+ red[index + width] * kernel[2][1] + red[index + width + 1] * kernel[2][2];
color = (int) Math.floor(Math.sqrt(firstPass * firstPass + secondPass * secondPass));
}
if (color > 255) {
color = 255;
}
// ... color turned into an ARGB integer argb
destImage.setRGB(x, y, argb);
}
}
나는 filterPixel 간단한 그레이 스케일 필터 때 다음과 같은 코드가 잘 작동으로 오류가, 위의 두 블록에 의심
병렬 필터 작업자 :
private static final int loadPerInterval = 500;
private static volatile int dynamicLoadCounter = 0;
public static synchronized void resetDynamicLoadCounter() {
dynamicLoadCounter = -loadPerInterval;
}
public void run() {
if (checkNull()) {
return;
}
int localCounter = loadPerInterval - 1;
int start = 0;
while (dynamicLoadCounter < width * height) {
localCounter++;
if (localCounter == loadPerInterval) {
//fetch a package of pixels to work on and mark them as being worked on
start = syncCounterUp();
System.out.println("#" + threadID + " starting at " + start);
localCounter = 0;
}
if (start + localCounter < width * height) {
filterPixel(start + localCounter);
} else {
return;
}
}
}
private static synchronized int syncCounterUp() {
dynamicLoadCounter += loadPerInterval;
return dynamicLoadCounter;
}
무엇이 잘못 되었나요? 동기화가 누락 되었습니까? 나는 내 스레드가 정확히 무엇을하고 있으며 왜이 유물이 나타나는 지에 대한 설명에 매우 흥미가있을 것입니다. 모양을 가져 주셔서 감사합니다!
나는 도움을 얻으려고했다. 나쁘다. – JayEff
코드에서 무엇이 잘못되었는지 파악하는 것이 약간 어렵습니다. 도움이되는 것은 단일 스레드를 사용할 때 이미지와 결과를 보여주는 것입니다. – FiReTiTi
@JayElf 그래서 자기 연민에 빠지기 전에 문제를 해결하기 위해 인터넷에있는 사람들에게 고통스러운 한 시간을 성공적으로 기다렸습니다. 나는 당신의 코드가 무엇을 해야할지 알아 내기 위해 1 시간이 필요하다. 샘플 입력, 출력 및 실행 가능한 기본 방법을 제공하십시오. – Gilfoyle