-2

我已经实现了生命游戏的顺序版本,但现在我想并行化它。我尝试使用从此处的一个答案中获得的建议,但现在尝试编译时出现错误。错误说“无效使用非静态成员函数 CalcRow”,然后它给出的行是:threads.push_back(thread(CalcRow, board, row)); 不知道如何修复它。我尝试将其声明为静态,但这不起作用,它仍然给出相同的错误。

这是我对并行实现的尝试:

GameOfLife.h:

#include <vector>
#include <thread>
using namespace std;


class GameOfLife {

    public:

        vector<vector<int> > SimulateLife(vector<vector<int> > &board, int life_cycles);

    private:

        vector<vector<int> > board;
        vector<vector<int> > nextBoard;

        int CheckNeighbors(vector<vector<int> > &board, int row, int col);
        void CalcRow(vector<vector<int> > &board, int row);
};


//Checks all 8 neighbors of the current cell to see if they are alive
//If they are alive add one to liveNeighbors

int GameOfLife::CheckNeighbors(vector<vector<int> > &board, int row, int col) {
    int liveNeighbors = 0;

    if(board[(board.size()+row-1)%board.size()][(board.size()+col-1)%board.size()] == 1)
        liveNeighbors++;

    if(board[(board.size()+row-1)%board.size()][col] == 1)
        liveNeighbors++;

    if(board[(board.size()+row-1)%board.size()][(board.size()+col+1)%board.size()] == 1)
        liveNeighbors++;

    if(board[row][(board.size()+col+1)%board.size()] == 1)
        liveNeighbors++;

    if(board[(board.size()+row+1)%board.size()][(board.size()+col+1)%board.size()] == 1)
        liveNeighbors++;

    if(board[(board.size()+row+1)%board.size()][col] == 1)
        liveNeighbors++;

    if(board[(board.size()+row+1)%board.size()][(board.size()+col-1)%board.size()] == 1)
        liveNeighbors++;

    if(board[row][(board.size()+col-1)%board.size()] == 1)
        liveNeighbors++;

    return liveNeighbors;
}


void GameOfLife::CalcRow(vector<vector<int> > &board, int row) {
    vector<int> x;

    for(int col = 0; col < board.size(); col++) {
        int aliveNeighbors = 0;

        if(board[row][col] == 2) 
            x.push_back(2);

        else if(board[row][col] == 1) {
            aliveNeighbors = CheckNeighbors(board, row, col);
            if(aliveNeighbors < 2 || aliveNeighbors > 3)
                x.push_back(0);
            else
                x.push_back(1);

        }

        else if(board[row][col] == 0) {
            aliveNeighbors = CheckNeighbors(board, row, col);
            if(aliveNeighbors == 3)
                x.push_back(1);
            else
                x.push_back(0);
        }
    }    

    nextBoard.swap(board);
}


vector<vector<int> > GameOfLife::SimulateLife(vector<vector<int> > &board, int life_cycles) {
    vector<thread> threads;

    for(int cycles = life_cycles; cycles > 0; cycles--) {
        for(int row = 0; row < board.size(); row++)
            threads.push_back(thread(CalcRow, board, row);

        for(int i = 0; i < threads.size(); i++)
            threads[i].join();
    }

    return board;
}    

主.cc:

#include <iostream>
#include <vector>
#include <thread>
#include "GameOfLife.h"
using namespace std;


void print_board(vector<vector<int> > &board) {
    int n = board.size();

    for (int i=0;i<n;i++) {
        for (int j=0;j<n;j++) {
            cout << board[i][j] << " ";
        }
        cout << endl;
    }
}


int main() {
    int n;
    cin >> n;

    vector<vector<int> > board;
    board.resize(n);

    for (int i=0;i<n;i++) {
        board[i].resize(n);
        for (int j=0;j<n;j++) {
            cin >> board[i][j];
        }
    }

    int k;
    cin >> k;

    GameOfLife obj;
    vector<vector<int> > result;
    result = obj.SimulateLife(board,k);
    print_board(result);
}
4

1 回答 1

1

这是我将如何做的概述。

我会做两个板,当前板和下一个板。

我会为行数创建一个线程向量。

使用当前数据计算一个新行来启动每个线程。您将希望在线程本地创建一个行,该行在完成后被复制以防止幽灵共享。

加入所有线程以确保完全计算板。

交换板子,重复。

于 2019-02-26T18:02:51.530 回答