ForkJoin - brak efektu

0

Cześć,
Zrobilem projekt w ktorym z kamerki z laptopa pobieram obraz, a nastepnie konwertuje pikseli z RGB na odcien szarosci.
I jak zmieniam liczbe workerow to kompletnie czas sie nie zmniejsza, a nawet mam wrazenie, ze zwieksza. Jest bardzo losowy.
Raz 40ms, potem 60ms, czasem 100ms. i w sumie mam wrazenie ze najlepiej dziala, jak nie uruchamia sie wiecej niz jeden wątek.

0

Ale co ty robisz w tych wątkach? I ile ich startujesz? I ile masz rdzeni? No i generalnie takich rzeczy nie robi się na CPU.

0

Mam Intel Core i7-8750H: 6 rdzeni 12 wątków
A startuje ich bardzo różnie: od 1 do ok 65000. Dla celow edukacyjnych. Projekt uczelniany.

1

Trudno mi powiedziec o obrabianiu grafiki, ale wiem że jak stosowałem ForkJoina do merge-sorta to było widac rezultaty (jakies 4 razy szybsze wykonanie średnio o ile dobrze pamiętam). No i generalnie jak działa Twój algorytm? Wypadałoby wstawic kod :)

0
   @Override
    public void compute() {
        if((startHeight-endHeight)*(startWidth-endWidth)<limit){

            computeDirectly();
            //System.out.println("start_H:" + startHeight + "end_heoght" + endHeight + "start_Width" + startWidth + "end_width" + endWidth);
            return;
        }
        int splitWidth = (endWidth - startWidth) / 2;
        int splitHeight = (endHeight - startHeight) / 2;
        invokeAll(new SplitAndDo(sourceImg, destinationIMG, limit,
                        startWidth, startHeight, startWidth+ splitWidth, startHeight+ splitHeight,filtrID),
                new SplitAndDo(sourceImg, destinationIMG, limit,
                        startWidth+ splitWidth,startHeight+ splitHeight, endWidth, endHeight,filtrID));
        invokeAll(new SplitAndDo(sourceImg, destinationIMG, limit,
                        startWidth+ splitWidth, startHeight, endWidth, startHeight+ splitHeight,filtrID),
                new SplitAndDo(sourceImg, destinationIMG, limit,
                        startWidth,startHeight+ splitHeight, startWidth+ splitWidth, endHeight,filtrID));


if (webCam.isOpened()) {
            Thread.sleep(1000);
            int tmp=0;
            while (true) {
                webCam.read(webcam_image);
                long startTime = System.currentTimeMillis();
                if (!webcam_image.empty()) {
                    matToBufferedImageConverter.setMatrix(webcam_image, ".jpg");
                    BufferedImage bufImg = matToBufferedImageConverter.getBufferedImage();
                    BufferedImage dstImage = bufImg;
                    SplitAndDo split = new SplitAndDo(bufImg, dstImage, workerService.getLimit(), 0, 0, bufImg.getWidth(), bufImg.getHeight(),filtrCase);
                    ForkJoinPool pool = new ForkJoinPool();
                    pool.invoke(split);
                    Net net = new Net();
                    net.drawNet(dstImage, dstImage, workerService.getNumberOfDivision());
                    facePanel.setFace(dstImage) ;
                    facePanel.setWorkers(workerService);
                    facePanel.repaint();
                    long endTime = System.currentTimeMillis();
                    facePanel.setTime((endTime - startTime));
                } else {
                    System.out.println("!!!Nothing captured from webcam!!!");
                    break;
                }
            }
            webCam.release();
        }

4

65000

xD No to powodzenia :D Przecież context switch zje ci tu cały czas procesora. Jak masz operacje CPU intensive to nie ma sensu robić więcej wątków niż masz rdzeni.

Czy ja dobrze czytam, ze robisz tam split po jednym pikselu na wątek? Wygląda to bardzo źle, bo coś takiego zabije ci CPU cache.

To nie jest tak, ze jak się coś odpali na milion wątków to nagle będzie szybsze. Należy sensownie wybrać fragment kodu który da się liczyć współbieżnie/równolegle. Dodatkowo pytanie brzmi ile czasu zabierają te operacje niezwiązane z tymi wątkami. Bo jeśli wczytanie danych z kamery i namalowanie wyniku zajmuje 90% czasu, to jakiekolwiek cudowanie z wątkami poprawi ci tylko te pozostałe 10% i w ogóle nie warto. A przypuszczam że tak właśnie jest i to ze to I/O zjada tu cały czas a nie ta konwersja.

1 użytkowników online, w tym zalogowanych: 0, gości: 1