Created
August 6, 2016 12:02
-
-
Save kell18/ad0b83794ee4298dbe3d51339cf076ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Правила игры "Жизнь" | |
если потенциал клетки равен двум, то клетка сохраняет свое состояние; | |
если потенциал равен трем, то клетка оживает; | |
если потенциал меньше двух или больше трех, то клетка погибает. | |
*/ | |
#include <iostream> | |
#include <cstdlib> /* srand, rand */ | |
#include <iostream> | |
#include <iomanip> | |
#include <omp.h> | |
#include <immintrin.h> | |
typedef __int64 COUNTER_TYPE; | |
static void Generate(bool *table, COUNTER_TYPE N) | |
{ | |
for (COUNTER_TYPE i = 0; i < N; ++i) | |
{ | |
table[i] = rand() % 4 == 1; | |
} | |
COUNTER_TYPE i, j; | |
#pragma omp parallel for shared(table) //collapse(2) | |
for (i = 1; i < N; ++i) | |
for (j = 0; j < N; ++j) | |
{ | |
COUNTER_TYPE index = (i*i + j*j); | |
table[i * N + j] = table[index % N]; | |
} | |
} | |
static int CalcPotential(COUNTER_TYPE i, COUNTER_TYPE j, bool *table, COUNTER_TYPE N) | |
{ | |
int p = 0; | |
for (long long x = i - 1; x <= i + 1; x++) | |
for (long long y = j - 1; y <= j + 1; y++) | |
{ | |
long long x1 = x; | |
long long y1 = y; | |
if (x1 == i && y1 == j) | |
continue; | |
if (x1 == -1) | |
x1 += N; | |
if (x1 == N) | |
x1 = 0; | |
if (y1 == -1) | |
y1 += N; | |
if (y1 == N) | |
y1 = 0; | |
if (table[x1 * N + y1]) | |
p++; | |
} | |
return p; | |
} | |
// посчитать количество живых клеток | |
// может быть оптимизировано!!! | |
static COUNTER_TYPE Calculate(bool *table, COUNTER_TYPE N) | |
{ | |
COUNTER_TYPE i, sum = 0; | |
for (i = 0; i < N*N; ++i) | |
{ | |
sum += table[i]; | |
} | |
return sum; | |
} | |
/*если потенциал клетки равен двум, то клетка сохраняет свое состояние; | |
если потенциал равен трем, то клетка оживает; | |
если потенциал меньше двух или больше трех, то клетка погибает.*/ | |
// может быть оптимизировано!!! | |
static bool lifeRules(int p, bool state) | |
{ | |
if (state) | |
{ | |
if (p < 2 || p > 3) | |
return false; | |
else | |
return true; | |
} | |
else | |
{ | |
if (p == 3) | |
return true; | |
else | |
return false; | |
} | |
}; | |
double lifeOriginal(int seed, size_t dimension, size_t n_iterations, size_t& alive) | |
{ | |
COUNTER_TYPE N = dimension; | |
COUNTER_TYPE IterationCount = n_iterations; | |
srand(seed); | |
bool *table = (bool*)malloc(sizeof(bool)*N*N); | |
bool *tableNew = (bool*)malloc(sizeof(bool)*N*N); | |
// заполняем поле | |
Generate(table, N); | |
double t = omp_get_wtime(); | |
//print(table, N, N); | |
//std::cout << std::endl; | |
COUNTER_TYPE it = 0, i = 0, j = 0; | |
// основной цикл расчета | |
// может быть оптимизировано!!! | |
while (it++ < IterationCount) | |
{ | |
for (i = 0; i < N; ++i) | |
for (j = 0; j < N; ++j) | |
{ | |
// считаем количество соседей | |
int p = CalcPotential(i, j, table, N); | |
// вычисляем новое состояние клетки | |
tableNew[i * N + j] = lifeRules(p, table[i * N + j]); | |
} | |
std::swap(table, tableNew); | |
} | |
// считаем количество выживших | |
alive = Calculate(table, N); | |
//print(table, N, N); | |
// осводождаем память | |
free(table); | |
free(tableNew); | |
return omp_get_wtime() - t; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment