Skip to content

Instantly share code, notes, and snippets.

@kell18
Created August 6, 2016 12:02
Show Gist options
  • Save kell18/ad0b83794ee4298dbe3d51339cf076ac to your computer and use it in GitHub Desktop.
Save kell18/ad0b83794ee4298dbe3d51339cf076ac to your computer and use it in GitHub Desktop.
/*
Правила игры "Жизнь"
если потенциал клетки равен двум, то клетка сохраняет свое состояние;
если потенциал равен трем, то клетка оживает;
если потенциал меньше двух или больше трех, то клетка погибает.
*/
#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