Производительность последовательных и параллельных вычислений с недорогими задачами - PullRequest
0 голосов
/ 07 мая 2020

У меня есть список объектов «Ячейка», которые представляют текущий статус.

List<Cell> currentCells = new ArrayList<Cell>();

Я хочу обновить текущий статус в al oop, вычислив будущий статус (новый список ячеек), а затем заменить на «текущий статус = будущий статус» " и так далее. Для этого у каждой ячейки есть метод, который возвращает новый объект ячейки, представляющий ее будущее. Этот метод имеет простые математические операции. Никаких зависимостей от других расчетов нет. Таким образом, теоретически будущие ячейки могут быть вычислены в параллельных потоках. чтобы достичь до 25 циклов в секунду.

Если я вычисляю его последовательно, мой l oop повторяется 3 раза в секунду. Если я выполняю сильное распараллеливание, делая каждую ячейку вызываемой и помещая их в ExecuterService, мой l oop повторяется только с 0,5 в секунду.

List<Future<Cell>> futures = taskExecutor.invokeAll(cells);

Я знаю, что решение проблемы параллельно всегда нужны накладные расходы. В этом случае это ускоряет мой l oop. Какой метод вы можете порекомендовать для ускорения моего l oop?

1 Ответ

0 голосов
/ 07 мая 2020

В любом случае, похоже, не будет никакой разницы в скорости, если я изменю numberOfThreads с 1 до 12 (у меня максимум 12 процессоров). Код моего l oop:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import view.ConsolePrinter;

public class Engine implements Runnable {

    private int numberOfThreads = 8;
    private boolean shouldRun = false;
    private ExecutorService taskExecutor;
    private Thread loopThread;
    private List<Cell> cells;
    private World world;
    private int numberOfRunningTimeSteps = 0;
    private int FPS = 30;
    private double averageFPS;

    public Engine(List<Cell> cells, World world) {
        this.cells = cells;
        taskExecutor = Executors.newFixedThreadPool(numberOfThreads);
        this.world = world;
    }

    @Override
    public void run() {

        world.resetTime();
        shouldRun = true;

        long startTime;
        long estimatedTimeMillis;
        long waitTime;
        long totalTime = 0;
        long targetTime = 1000 / FPS;

        int frameCount = 0;
        int maxFrameCount = 1; 

        while (shouldRun) {

            startTime = System.nanoTime();

            try {
                List<Future<Cell>> futures = taskExecutor.invokeAll(cells);
                List<Cell> futureCells = new ArrayList<Cell>();

                futures.forEach((future) -> {
                    try {
                        futureCells.add(future.get());
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }

                });

                world.setCells(futureCells);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            world.timeProceeded();

            if (numberOfRunningTimeSteps != 0 && world.getTime() == numberOfRunningTimeSteps) {
                shouldRun = false;
            }

            estimatedTimeMillis = (System.nanoTime() - startTime) / 1000000;
            waitTime = targetTime - estimatedTimeMillis;
            try {
                if (waitTime > 0.0) {
                    Thread.sleep(waitTime);
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            totalTime += System.nanoTime() - startTime;
            frameCount++;
            if (frameCount == maxFrameCount) {
                averageFPS = 1000.0 / ((totalTime / frameCount) / 1000000);

                frameCount = 0;
                totalTime = 0;
            }
        }

    }

    public void start(int n) {
        loopThread = new Thread(this);
        loopThread.start();
        numberOfRunningTimeSteps = n;
    }

    public void stop() {
        shouldRun = false;

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...