Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LO21_Pin_Noir_Boucher_Bouri_Detree
CellulutLO21
Commits
a829fbcc
Commit
a829fbcc
authored
Jun 06, 2021
by
Yann Boucher
Browse files
Performance improvements : 4x better for the Game of Life rule on a 1M cells grid
parent
7346c3ae
Pipeline
#79263
failed with stage
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
include/grid.h
View file @
a829fbcc
...
...
@@ -50,6 +50,13 @@ public:
//! \brief Initialise la cellule de coordonnée pos à l'état 'state'
void
set_cell
(
Coord
pos
,
unsigned
int
state
)
{
// fast path
if
(
pos
.
x
>=
0
&&
pos
.
y
>=
0
&&
pos
.
x
<
nb_col
&&
pos
.
y
<
nb_rows
)
{
matrix
[
pos
.
y
*
nb_col
+
pos
.
x
]
=
state
;
return
;
}
int
i
=
pos
.
y
;
int
j
=
pos
.
x
;
matrix
[((
i
%
nb_rows
+
nb_rows
)
%
nb_rows
)
*
nb_col
...
...
@@ -60,6 +67,12 @@ public:
//! \brief Retourne l'état d'une cellule
//! \return Retourne l'état d'une cellule de coordonnées pos
unsigned
int
get_state
(
Coord
pos
)
const
{
// fast path
if
(
pos
.
x
>=
0
&&
pos
.
y
>=
0
&&
pos
.
x
<
nb_col
&&
pos
.
y
<
nb_rows
)
{
return
matrix
[
pos
.
y
*
nb_col
+
pos
.
x
];
}
int
i
=
pos
.
y
;
int
j
=
pos
.
x
;
return
matrix
[((
i
%
nb_rows
+
nb_rows
)
%
nb_rows
)
*
nb_col
...
...
include/neighborhood.hpp
View file @
a829fbcc
...
...
@@ -7,18 +7,21 @@
Cette classe représente le voisinage d'une cellule.
**/
**/
#ifndef NEIGHBOURHOOD_HPP
#define NEIGHBOURHOOD_HPP
#include <map>
#include <vector>
#include <utility>
#include <string>
#include <algorithm>
#include "coord.hpp"
#include "state.hpp"
using
namespace
std
;
using
namespace
std
;
//! \brief Exception lancée lors d'une erreur de manipulation d'un voisinage.
class
NeighborhoodException
:
public
std
::
exception
...
...
@@ -35,34 +38,43 @@ public:
//! \brief Classe représentant un voisinage, c'est à dire une liste de cellules dont leur état et leur position.
class
Neighborhood
{
//! \brief Map de voisins contenant la position relative et l'état du voisin
map
<
Coord
,
unsigned
int
>
neighborPositions
;
//! \brief vector de voisins contenant la position relative et l'état du voisin
mutable
vector
<
pair
<
Coord
,
unsigned
int
>>
neighborPositions
;
//! \brief Contient le nombre de voisins d'état i : counts[i] contient le nb de voisins d'état i, ou 0 si i >= counts.size()
std
::
vector
<
unsigned
>
counts
;
mutable
bool
sorted
;
public:
//! \brief Fonction vérifiant que la coordonnée d'un voisin que l'on souhaite ajouter dans le vecteur neighborPositions est unique
//! \param Coord : Coordonnée à comparer
//! \return retourne vrai si la coordonnée est unique sinon faux s'il existe un doublon
bool
isUnique
(
Coord
c
)
const
;
//! \brief Retourne le nombre de voisin ayant l'état définit en paramètre
//! \param State : Etat des voisins à rechercher
//! \return Le nombre de voisin
unsigned
int
getNb
(
unsigned
int
s
)
const
;
//! \brief Retourne l'état de la cellule voisine située à la coordonnée relative entrée en paramètre
//! \param Coordonnée du voisin à trouver
//! \return L'état de la cellule
unsigned
int
getAt
(
Coord
c
)
const
;
//! \brief Ajoute un voisin au vecteur des voisins. Prend une coordonnée et un état en paramètre
//! \param Coord, State : coordonée relative et état du voisin
void
addNeighbor
(
Coord
c
,
unsigned
int
s
)
{
if
(
isUnique
(
c
))
neighborPositions
[
c
]
=
s
;
//! \brief Initialisation du Neighborhood
Neighborhood
()
{
neighborPositions
.
reserve
(
8
);
counts
.
reserve
(
8
);
sorted
=
false
;
}
//! \brief Retourne le nombre de voisin ayant l'état définit en paramètre
//! \param State : Etat des voisins à rechercher
//! \return Le nombre de voisin
unsigned
int
getNb
(
unsigned
int
s
)
const
{
if
(
s
>=
counts
.
size
())
return
0
;
else
throw
NeighborhoodException
(
"La coordonnée existe déjà.
\n
"
);
}
return
counts
[
s
];
}
//! \brief Ajoute un voisin au vecteur des voisins. Prend une coordonnée et un état en paramètre
//! \param Coord, State : coordonée relative et état du voisin
//! \pre La coord ne doit pas déjà exister
void
addNeighbor
(
Coord
c
,
unsigned
int
s
)
{
sorted
=
false
;
neighborPositions
.
push_back
({
c
,
s
});
if
(
s
>=
counts
.
size
())
counts
.
resize
(
s
+
1
,
0
);
++
counts
[
s
];
}
//! \brief Retourne une copie du voisinage, miroir selon l'axe vertical.
Neighborhood
flip_vertically
()
const
;
...
...
@@ -80,9 +92,16 @@ public:
{
if
(
i
>=
size
())
throw
NeighborhoodException
(
"Index invalide
\n
"
);
auto
it
=
neighborPositions
.
begin
();
std
::
advance
(
it
,
i
);
return
*
it
;
if
(
!
sorted
)
{
std
::
sort
(
neighborPositions
.
begin
(),
neighborPositions
.
end
(),
[](
const
pair
<
Coord
,
unsigned
int
>&
lhs
,
const
pair
<
Coord
,
unsigned
int
>&
rhs
)
{
return
lhs
.
first
<
rhs
.
first
;
});
sorted
=
true
;
}
return
neighborPositions
[
i
];
}
};
...
...
src/neighborhood.cpp
View file @
a829fbcc
#include "neighborhood.hpp"
unsigned
int
Neighborhood
::
getNb
(
unsigned
int
s
)
const
{
unsigned
int
res
=
0
;
for
(
auto
it
=
neighborPositions
.
begin
();
it
!=
neighborPositions
.
end
();
++
it
)
{
if
(
it
->
second
==
s
)
{
res
++
;
}
}
return
res
;
}
unsigned
int
Neighborhood
::
getAt
(
Coord
c
)
const
{
if
(
!
neighborPositions
.
count
(
c
))
throw
NeighborhoodException
(
"Error Neighborhood::getAt"
);
return
neighborPositions
.
at
(
c
);
}
Neighborhood
Neighborhood
::
flip_vertically
()
const
{
Neighborhood
n
;
...
...
@@ -51,7 +30,3 @@ Neighborhood Neighborhood::rotate90() const
return
n
;
}
bool
Neighborhood
::
isUnique
(
Coord
c
)
const
{
return
neighborPositions
.
count
(
c
)
==
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment