2013-12-13 68 views
0

我正在做一個並行的圖像處理程序,我有4個內核,所以當我在少於5個的線程上運行程序時,應該比僅在1個線程上運行時有所改進,我想那裏沒有任何改進,因爲圖片可能太小,所以由於線程而導致開銷。所以我用8142x2175圖片仍然沒有任何改進。問題來自Eclipse嗎?當我添加更多的線程處理時間增加?

這是我的主要圖像處理程序,我包括類之一,你可以看到我使用Java和Eclipse的運行它。

public class Main { 
    public static void main(String[] args) throws IOException { 

     final File imageFile= new File ("C:\\Users\\user\\Desktop\\Parallel\\pic8142x2175.jpg"); 
     BufferedImage orgImg= ImageIO.read(imageFile); 

     // the destination buffered image 
     BufferedImage destImg = new BufferedImage(orgImg.getWidth(), orgImg.getHeight(), 
         BufferedImage.TYPE_INT_RGB); 

     // let the user enter number of thread 
     System.out.println(" please enter number of threads"); 
     Scanner in = new Scanner(System.in); 
     int nThreads=in.nextInt(); 

     // create the threads 
     ExecutorService executor = Executors.newFixedThreadPool(nThreads); 

     // assign each thread with its own runnable 
     for (int i=0; i<nThreads;i++){ 

      //Runnable gsr = new GreyscaleRunnable(orgImg, i, nThreads,destImg); 
      //Runnable pr = new PixelateRunnable(orgImg,20,i,nThreads,destImg); 
      Runnable fr= new FlipRunnable(orgImg,i,nThreads,destImg); 
       executor.execute(fr); 

      }// end of for loop 

     // This will make the executor accept no new threads 
     // and finish all existing threads in the queue 
     executor.shutdown(); 
     // Wait until all threads are finish 


    } 

} 

FlipRunnable類

public class FlipRunnable implements Runnable{ 

    private BufferedImage img; 
    private BufferedImage dest; 
    private int my_rank, thread_count; 

    // constructor of the class 
     public FlipRunnable(BufferedImage img,int my_rank,int thread_count,BufferedImage dest) { 
      this.img=img; 
      this.my_rank=my_rank; 
      this.thread_count=thread_count; 
      this.dest=dest; 
     } 

     long startTime = System.currentTimeMillis(); 

    @Override 
    public void run() { 

     int localRows = img.getHeight()/thread_count; 
     int myFirstRow = my_rank * localRows; 
     int myLastRow = (my_rank + 1) * localRows - 1; 

     for (int i = myFirstRow; i <= myLastRow; i++) { 
      for (int j = 0; j < img.getWidth(); j++){ 

       int px = img.getRGB(j, i); 

       dest.setRGB(img.getWidth() - j - 1, i, px); 


      }// end of j loop 

     }// end of i loop 

     String dstName = "C:\\Users\\user\\Desktop\\Parallel\\funFlipped.jpg"; 
     File dstFile = new File(dstName); 
     try { 
      ImageIO.write(dest, "jpg", dstFile); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     System.out.println("Output image: " + dstName); 

     // the total time 
     long endTime = System.currentTimeMillis(); 
     long totalTime = endTime - startTime; 
     System.out.println("time is:"+totalTime); 
    } 

} 
+2

首先,每個工人似乎覆蓋目標圖像... –

+4

另外,'setRGB()''是synchronized',所以必須有大量爭的工人之間。看起來你更好地將圖像複製到普通數組並在那裏工作。 –

+0

是的,我希望工作人員互相覆蓋,這樣我就可以得到整個圖像,而不僅僅是線程工作的部分。對不起我的英語,我試圖說的是,當我沒有讓工人覆蓋,我的輸出只是圖像的一部分,這樣我就完成了整個圖像 – user3099142

回答

0

我想有點改進的事實,setRGB()是​​方法造成的,所以有很多的工作線程之間的爭論。您需要將圖像數據複製到陣列並在那裏工作。

0

隨着線程數量的增加,有一些由OS切換線程上下文之間做更多的努力。

理想的情況下,線程數不應超過Runtime.getRuntime().availableProcessors()更大。這通常會返回CPU核心的數量(超線程將返回每個核心2個線程)。

0

首先,您正在嘗試從所有主題處理相同的圖片!舒爾在性能上不會有任何改進,因爲你在同步dest.setRGB(...)中遇到瓶頸。

編輯:@Victor索羅金是正確的評論質疑。

+1

如果線程之間沒有或很少有爭用,並且沒有創建冗餘線程(即線程數量不超過CPU內核數量),那麼**會改進對來自多個線程的相同數據的處理。另外,數據的大小不能太小,以便線程切換可以消除任何性能增益。但對於OP數據大小,情況並非如此。 –

+0

@Victor Sorokin,啊,好的,我明白了!然後,如你所說,在dest.setRGB()中同步是瓶頸。 – traylz