virtual void do_run(TaskData & td, std::unique_ptr<AResult> & ares) override { Threading::CustomRandomData & d = static_cast<Threading::CustomRandomData&>(td); D() << "initial data" << d.get_const(); std::size_t threads_count = d.get_num_threads(); init(threads_count); std::vector<std::thread> threads; threads.reserve(threads_count); for(std::size_t i=0; i<threads_count; ++i) { /* Cant simply use [&](){do_thread()} here. * i will be captured by reference and may be incremented before * passing to do_thread. We need at least [this,i,&d](){} * */ threads.push_back(std::thread([&,i](){do_thread(d, i);})); } for (auto & t : threads) t.join(); std::unique_ptr<Threading::result_type> result(new Threading::result_type(0)); gather_results(*result); ares->set_custom_result(std::move(result)); }
int main() { int *result[2] = {NULL}; gather_results(result); free_all(result[0], result[1]); exit(EXIT_SUCCESS); }
// TODO: add player payments for chance/chest int main(int argc, char ** argv) { struct timeval t1, t2; MPI_Init(&argc, &argv); gettimeofday(&t1, NULL); int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &globalrank); MPI_Comm_size(MPI_COMM_WORLD, &size); globalsize = size; srand(time(NULL) + globalrank); struct location board[BSIZE]; struct player players[NUMPLAYERS]; int itr = 10000; long long bills[4]; // how much you owe each player at end of round init_players(players); init_board(board); char plocation; int pvalue; int numcomms = 1; MPI_Group world_group; MPI_Comm_group(MPI_COMM_WORLD, &world_group); playerdata d; d.money[0] = 0; d.money[1] = 0; d.money[2] = 0; d.money[3] = 0; output = (FILE **) malloc(size * sizeof(FILE *)); // if 1 process created just run sequentially if (size == 1) { int done[4] = {1, 1, 1, 1}; while (itr) { itr--; int i; for (i = 0; i < NUMPLAYERS; i++) { plocation = 0; pvalue = 0; if (players[i].money > 0) { move(players, board, i, &pvalue, &plocation); if (plocation) { board[plocation].owner = i; players[i].money -= pvalue; } } else { players[i].order = -1; if (done[i]) { remove_properties(board, i); done[i] = 0; } } } } gettimeofday(&t2, NULL); results(players, board); double exectime = (t2.tv_sec - t1.tv_sec) * 1000000 + ((t2.tv_usec - t1.tv_usec)); printf("Exec Time %lf\n", exectime); return 0; } // create a communicator for each monopoly game (for n > 4) MPI_Group * gamesel; MPI_Comm * games; int ranksel[4]; if (size > 4) { numcomms = size / 4; games = (MPI_Comm *) malloc(numcomms * sizeof(MPI_Comm)); gamesel = (MPI_Group *) malloc(numcomms * sizeof(MPI_Group)); int i; for (i = 0; i < numcomms; i++) { ranksel[0] = 4 * i; ranksel[1] = 4 * i + 1; ranksel[2] = 4 * i + 2; ranksel[3] = 4 * i + 3; MPI_Group_incl(world_group, 4, ranksel, &gamesel[i]); MPI_Comm_create(MPI_COMM_WORLD, gamesel[i], &games[i]); } } else { // n < 4 so use MPI_COMM_WORLD games = (MPI_Comm *) malloc(1 * sizeof(MPI_Comm)); games[0] = MPI_COMM_WORLD; numcomms = 1; } // create an MPI type so that we can use our player data struct in MPI communication calls const int nitems = 5; int blocklengths[5] = {4, 1, 1, 1, 1}; MPI_Datatype types[5] = {MPI_LONG_LONG, MPI_INT, MPI_CHAR, MPI_CHAR, MPI_CHAR}; MPI_Datatype MPI_MONO_DATA; MPI_Aint offsets[5]; offsets[0] = offsetof(playerdata, money); offsets[1] = offsetof(playerdata, pvalue); offsets[2] = offsetof(playerdata, plocation); offsets[3] = offsetof(playerdata, order); offsets[4] = offsetof(playerdata, trade); MPI_Type_create_struct(nitems, blocklengths, offsets, types, &MPI_MONO_DATA); MPI_Type_commit(&MPI_MONO_DATA); MPI_Comm_rank(games[globalrank / 4], &rank); #ifdef DEBUG char fname[10]; snprintf(fname, 10, "mon%d.dbg", globalrank); output[globalrank] = fopen(fname, "w"); fprintf(output[globalrank], "MAIN begin loop\n"); print_board_info(board); #endif // run the game for 40000 turns (10000 per player) while (itr > 0) { itr--; pvalue = 0; plocation = 0; d.trade = 0; d.order = rank; #ifdef DEBUG fprintf(output[globalrank], "MAIN tag 1 rank %d\n", rank); #endif move(players, board, rank, &pvalue, &plocation); d.pvalue = pvalue; d.plocation = plocation; #ifdef DEBUG fprintf(output[globalrank], "using comm %d\n", globalrank / 4); if (games[globalrank / 4] != MPI_COMM_WORLD) { fprintf(output[globalrank], "COMM ERROR\n"); } #endif send_info(&d, players, board, rank, games[globalrank / 4], MPI_MONO_DATA); #ifdef DEBUG fprintf(output[globalrank], "MAIN tag 3 rank %d\n", rank); print_board_info(board); #endif } #ifdef DEBUG fprintf(output[globalrank], "MAIN last tag rank %d\n", rank); #endif // get results from each process gather_results(players, board, games, numcomms, globalrank); gettimeofday(&t2, NULL); if (globalrank == 0) { results(players, board); } #ifdef DEBUG fclose(output[globalrank]); #endif double exectime = (t2.tv_sec - t1.tv_sec) * 1000000 + ((t2.tv_usec - t1.tv_usec)); if (globalrank == 0) { printf("Exec Time %lf\n", exectime); } MPI_Finalize(); return 0; }