User Tools

Site Tools


in204:tds:sujets:td8:part2

This is an old revision of the document!


Section critique

TD8

Références

Question n°1

Nous supposons que nous avons deux fonctions, une première fonction calcule la valeur maximale d’un tableau numérique :

void array_find_max(
	std::vector<int>::const_iterator begin, 
	std::vector<int>::const_iterator end, int* theMaxValue)
{
	if (begin != end)
	{
		int result = *begin;
		begin++;
		for (; begin != end; begin++)
			if (*begin > result)
				result = *begin;
		*theMaxValue = result;
	}
}

la seconde fonction modifie le tableau en multipliant chaque valeur numérique du tableau par 2 :

void array_multiply_by(
	std::vector<int>::iterator begin,
	std::vector<int>::iterator end, int theValue)
{
	for (; begin != end; begin++)
		*begin *= theValue;
}

Implanter chacune des fonctions.

Correction

Correction

Il suffit de recopier les fonctions dans un fichier main.cpp, d'ajouter l'inclusion include<vector> et de compiler.

Question 2

Pour tester les fonctions, nous devons créer des tableaux de taille conséquente. Ces tableaux peuvent-être créés par soit de manière aléatoire soit de manière cycliques. Ci-dessous quelques exemples de fonctions générant des tableaux de taille n et ayant comme valeur des nombres entre 0 et theMaxValue. Nous souhaitons exécuter en parallèle les deux fonctions.

void initialize_array(std::vector<int>& theArray, int theSize,
	int theMaxValue)
{
	theArray.clear();
        theArray.resise(theSize);
	int step = theMaxValue / 3;
	theArray[0] = 0;
	for (int i = 1; i < theSize; i++)
			theArray[i] = (theArray[i-1] + step) % (theMaxValue + 1);
}

Ou

#include<random>
 
void initialize_random_array(std::vector<int>& theArray, int theSize,
	int theMaxValue)
{
	static std::mt19937 gen(1729);
	std::uniform_int_distribution<> distrib(0, theMaxValue);
	theArray.clear();
	for (int i = 0; i < theSize; i++)
		theArray[i] = distrib(gen);
}

Correction

Correction

Nous pouvons utiliser pour ce faire une fonction de test du type suivant:

void test_valid_execution(std::vector<int>& theArray)
{
	// Get the max value of the array
	int referenceMaxValue = *(std::max_element(theArray.begin(), theArray.end()));
 
	// Execute both threads in parallel
	int maxValue;
        array_find_max(theArray.begin(), theArray.end(), &maxValue);
	if (referenceMaxValue != maxValue)
		std::cout << "Error when computing the max value: " << maxValue << " found, " << referenceMaxValue 
 
	array_multiply_by(theArray.begin(), theArray.end(), 2);
        array_find_max(theArray.begin(), theArray.end(), &maxValue);
	if (2*referenceMaxValue != maxValue)
		std::cout << "Error when computing the max value: " << maxValue << " found, " << 2*referenceMaxValue 
}
 
int main()
{
	std::vector<int> array;
	initialize_array(array, 10000, 100);
	test_valid_execution(array);
}

Question n°3

Nous souhaitons exécuter les deux fonctions précédents en parallèle.

Expliquer pourquoi les résultats ne sont pas toujours cohérents ? ie. que la valeur maximale retournée est supérieure à la valeur maximale du tableau spécifiée au montant de sa création.

Question n°4

Il faut utiliser un verrou qui permet à une méthode de se garantir l’exclusivité de l’usage du tableau. Pour ce faire, nous pouvons utiliser un objet std::mutex qui encapsule un mécanisme d’exclusion mutuelle. L’objet std::unique_lock permet d’obtenir un accès exclusif sur un object std::mutex. Quand nous écrivons le code suivant :

#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::unique_lock
 
std::mutex mtx;           // mutex fournissant le mécanisme d’exclusion mutuelle.
 
void my_function (int n, char c) {
	// section critique, tant que l'objet lck existe, personne ne pourra
	// accéder à mtx.
	std::unique_lock<std::mutex> lck(mtx);
	// Code s'exécutant.
}

Question n°3.1

Modifier les fonctions

int array_find_max(std::vector<int>& theArray, int* theMaxValue)

et

void array_multiply_by(std::vector<int>& theArray, int theValue)

pour implanter le mécanisme d’exclusion mutuelle propose.

Question n°3.2

Exécuter le code et vérifier que les résultats sont dorénavant cohérents.

in204/tds/sujets/td8/part2.1604336417.txt.gz · Last modified: 2020/11/02 17:00 by bmonsuez