【问题标题】:Java parallel for loop with parametr passing带参数传递的 Java 并行 for 循环
【发布时间】:2020-04-16 00:15:24
【问题描述】:

我希望 Java 1.8 中的这段代码能够在更多处理器上并行运行:

        // Make iterations
        for(int i = 0; i < numberOfIterations; i++) {
            for(int m = 0; m < gridsize; m++) {
                for(int n = 0; n < gridsize; n++) {
                    one_cell_generation(grid, grid2, m, n);
                }
                int n = 0;
            }

        }

这是生命游戏实现代码的一部分。我怎样才能使它并行,以便函数one_cell_generation 将在更多处理器(也许是线程?)上运行多次。我是 Java 新手。谢谢。这是我的生命游戏实现的全部代码:

package gameoflife;

public class GameOfLife {

    public static int gridsize = 5;
    public static int numberOfIterations = 100;
    public static String liveCell = "x";
    public static String deadCell = "o";

    public static void main(String[] args) {
        // Probability that cell is live in random order
        double p = 0.1;

        Boolean[][] grid = new Boolean[gridsize][gridsize];
        Boolean[][] grid2 = new Boolean[gridsize][gridsize];


        // Set up grid
        for(int m = 0; m < gridsize; m++) {
            for(int n = 0; n < gridsize; n++) {
                grid[m][n] = false;
                if(Math.random() < p) {
                    grid[m][n] = true;
                }
                // Copy grid
                grid2[m][n] = grid[m][n];
            }
        }

        // Make iterations
        for(int i = 0; i < numberOfIterations; i++) {
            for(int m = 0; m < gridsize; m++) {
                for(int n = 0; n < gridsize; n++) {
                    one_cell_generation(grid, grid2, m, n);
                }
                int n = 0;
            }

        }

        print_grid(grid);


    }

    public static void print_grid(Boolean[][] grid) {
        for(int m = 0; m < gridsize; m++) {
            for(int n = 0; n < gridsize; n++) {
                if(grid[m][n] == false) {
                    System.out.print(deadCell);
                } else {
                    System.out.print(liveCell);
                }

            }
            System.out.println();
        }
    }

    public static void one_cell_generation(Boolean[][] oldGrid, Boolean[][] newGrid, int m, int n) {
        // count live and dead neighbors
        int liveNeighbours = 0;
        // iterate over neighbors
        // check borders
        if(m > 0) {
            if(oldGrid[m-1][n] == true) {
                liveNeighbours += 1;
            }
            if (n > 0) {
                if(oldGrid[m-1][n-1] == true) {
                    liveNeighbours += 1;
                }
            }
            if(n < (gridsize - 1)) {
                if (oldGrid[m-1][n+1] == true) {
                    liveNeighbours += 1;
                }
            }
        }
        if (m < (gridsize - 1)) {
            if (oldGrid[m+1][n] == true) {
                liveNeighbours += 1;
            }

            if(n > 0) {
                if(oldGrid[m+1][n-1] == true) {
                    liveNeighbours += 1;
                }
            }
            if(n < (gridsize - 1)) {
                if(oldGrid[m+1][n+1] == true) {
                    liveNeighbours += 1;
                }
            }
        }

        if (n > 0) {
            if (oldGrid[m][n-1] == true) {
                liveNeighbours += 1;
            }
        }
        if(n < (gridsize - 1)) {
            if(oldGrid[m][n+1] == true) {
                liveNeighbours += 1;    
            }
        }

        // conway's game of life rules
        // apply rules to new grid
        if(liveNeighbours < 2 || liveNeighbours > 3) {
            newGrid[m][n] = false;
        }
        if(liveNeighbours == 3) {
            newGrid[m][n] = true;
        }
    }

}

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我不知道生命游戏的确切代码,但是看看你在这里粘贴的内容,concurrent modification execptions 的机会很大,你会怎么做?
  • 这并不像添加一些线程那么容易。已经有whole books 写在这个话题上。回答这个问题对于 StackOverflow 来说是题外话,因为它本质上意味着重组整个程序。即使程序在并行运行时按预期工作,也不能保证它实际上会减少执行时间。我最好的提示是:开始阅读。
  • @ShivamPuri 不需要收藏。可以轻松使用IntStream 遍历二维数组。
  • @Vault23 liveNeighbours 变量是方法的本地变量。每个线程都有自己的副本可以处理。没有风险,没有瓶颈。

标签: java multithreading multiprocessing


【解决方案1】:

外层循环是一个时间序列循环遍历不同代,所以不能并行化而不影响最终结果。

两个内循环根据上一代的状态计算当前代的状态,可以很方便的并行化。

这是一种使用parallelIntStream的方法:

static int numberOfIterations = 100;
static int gridSize = 5;

public static void main(String[] args) {
    Boolean[][] grid1 = new Boolean[gridSize][gridSize];
    Boolean[][] grid2 = new Boolean[gridSize][gridSize];

    // initialize grids here

    for(int i = 0; i < numberOfIterations; i++) {
        // parallel processing
        IntStream.range(0, gridSize * gridSize).parallel().forEach(mn -> {
            int m = mn / gridSize;
            int n = mn % gridSize;

            oneCellGeneration(grid1, grid2, m, n);
        });

        // copy new grid to old grid here
    }
}

public static void oneCellGeneration(Boolean[][] grid1, Boolean[][] grid2,
        int m, int n) {
    // your cell generation logic here
}

注 1: 我重命名了一些方法和变量以符合 Java 命名约定。
注 2: 您忘记将新网格复制到完成(或开始)原始代码中的一代之后的旧网格。

【讨论】:

    【解决方案2】:

    你可以这样做。我无法添加评论来回答,所以我创建了自己的答案。

        static int gridSize = 5;
    
        public static void main(String[] args) {
            Boolean[][] grid1 = new Boolean[gridSize][gridSize];
            Boolean[][] grid2 = new Boolean[gridSize][gridSize];
    
            // initialize grids here
    
                IntStream
                        .range(0, gridSize * gridSize)
                        .limit(numberOfIterations)
                        .parallel().forEach(mn -> {
                    int m = mn / gridSize;
                    int n = mn % gridSize;
    
                    oneCellGeneration(grid1, grid2, m, n);
                });
        }
    
        public static void oneCellGeneration(Boolean[][] grid1, Boolean[][] grid2,
                                             int m, int n) {
            // your cell generation logic here
        }
        ```
    

    【讨论】:

      猜你喜欢
      • 2020-08-12
      • 1970-01-01
      • 2018-04-26
      • 2015-02-17
      • 2011-09-27
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多