3.2.1.3.2 : Le fichier source

Écrivons le fichier hadamard_product_intrinsics.cpp :



Il nous faut tout d'abord inclure un header qui permet de définir l'alignement des données en float avec PLIB_VECTOR_SIZE_FLOAT. Ainsi que des fonctions intrisèques génériques telles que :
  • plib_load_ps : pour lire des registres vectoriels (par exemple 8 floats en AVX
  • plib_mul_ps : pour multiplier des registres vectoriels
  • plib_store_ps : pour sauvegarder des registres vectoriels


1
#include "phoenix_intrinsics.h"


Ensuite nous incluons notre header :

1
#include "hadamard_product_intrinsics.h"


Ensuite nous implémentons notre produit de hadamard en prennant en compte le fait que nous traitons plusieurs données en même temps, la boucle for est donc sur vecSize et non sur nbElement :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
///Do the Hadamard product
/**	@param[out] tabResult : table of results of tabX*tabY
 * 	@param tabX : input table
 * 	@param tabY : input table
 * 	@param nbElement : number of elements in the tables
*/
void hadamard_product_intrinsics(float* tabResult, const float* tabX, const float* tabY, size_t nbElement){
	size_t vecSize(PLIB_VECTOR_SIZE_FLOAT);
	size_t nbVec(nbElement/vecSize);
	for(size_t i(0lu); i < nbVec; ++i){
		PRegVecf vecX = plib_load_ps(tabX + i*vecSize);
		PRegVecf vecY = plib_load_ps(tabY + i*vecSize);
		PRegVecf vecRes = plib_mul_ps(vecX, vecY);
		plib_store_ps(tabResult + i*vecSize, vecRes);
	}
}


Le fichier hadamard_product_intrinsics.cpp complet :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/

#include "phoenix_intrinsics.h"

#include "hadamard_product_intrinsics.h"

///Do the Hadamard product
/**	@param[out] tabResult : table of results of tabX*tabY
 * 	@param tabX : input table
 * 	@param tabY : input table
 * 	@param nbElement : number of elements in the tables
*/
void hadamard_product_intrinsics(float* tabResult, const float* tabX, const float* tabY, size_t nbElement){
	size_t vecSize(PLIB_VECTOR_SIZE_FLOAT);
	size_t nbVec(nbElement/vecSize);
	for(size_t i(0lu); i < nbVec; ++i){
		PRegVecf vecX = plib_load_ps(tabX + i*vecSize);
		PRegVecf vecY = plib_load_ps(tabY + i*vecSize);
		PRegVecf vecRes = plib_mul_ps(vecX, vecY);
		plib_store_ps(tabResult + i*vecSize, vecRes);
	}
}


Vous pouvez le télécharger ici.