=====================================================================
author: Jean-Michel RICHER
email: jean-michel.richer@univ-angers.fr
date: April, 2019
=====================================================================


---------------------------------------------------------------------
1. DESCRIPTION
---------------------------------------------------------------------

Comparison of different implementations of a function that computes
the hypothetical DNA sequence z of two input sequences DNA x and y
of size residues. The function returns the number of mutations 
(or changes).

The code of the function is the following :

/**
 * Reference function
 * @return number of mutations
 * @param x first sequence
 * @param y second sequence
 * @param z hypothetical sequence
 * @param size size of sequences
 */
u32 maxpars_c(u8 *x, u8 *y, u8 *z, u32 size) {
	u32 mutations = 0;
	for (u32 i = 0; i < size; ++i) {
		z[i] = x[i] & y[i];
		if (z[i] == 0) {
			z[i] = x[i] | y[i];
			++mutations;
		}
	}
	return mutations;
}

The different functions that are implemented are the following :

1- maxpars_c_O2 : compiler with -O2 flags
2- maxpars_c_O3 : compiler with -O3 flags
3- maxpars_asm  : direct implementation of reference function
4- maxpars_sse2 : SSE2 implementation 
5- maxpars_sse2 : SSE4.1 implementation with pblendvb instead
                  of pand, por, pxor
6- maxpars_avx2 : AVX2 implementation 
7- maxpars_avx2_intrinsics : compiler AVX2 intrinsics


---------------------------------------------------------------------
2. INSTALLATION
---------------------------------------------------------------------

2.a Prerequisite

	You first need to install:
	
	- make 
	- nasm (The Netwide Assembler https://www.nasm.us/) 
	- g++ the GNU C++ compiler with multilib support
	- gnuplot to generate graphics
	- evince to view .pdf files
	- php to run the performance and validity scripts
	
	- eventually you can install other compilers like 
		-- icpc (Intel)
		-- clang (LLVM)
	  	-- pgc++ (PGI) 

	  	
	In a terminal type the following commands:
	  	
		> sudo apt install nasm make gcc-8 g++-8 
		> sudo gcc-multilib g++-multilib gnuplot evince   	
	  
2.b Compilation

	From the command line, just type 
	
		> make clean && make configure && make 
		
	or simply
	
		> make compile
		
	See INSTALL file if you wan to compile with debug options or 
	another compiler.
	
		
	All objects files and the binary will be sent to the 'build' 
	subdirectory that will be created in the main directory of the 
	project.
	
	Note that 'make configure' will generate the files 'src/cpp_config.h',
	'src/asm_config.inc' that contain definitions of macro and the files
	'cpu_technos_{compiler}.mak' that contains the vector technology 
	available on the CPU used for the tests

2.c Performance tests

	Performance tests will be executed by the './performance_test.php'
	script
	
	You can execute the compilation process followed by the test using 
	the 'run' target of make :
	
		> make run
		

---------------------------------------------------------------------	
3. RESULTS
---------------------------------------------------------------------

	All results will be put in the 'results/<cpu-name>' directory
	where <cpu-name> will be evaluated from '/proc/cpuinfo' using
	the './cpu_name.sh' script
	
	You can check the 'results' directory with some other results
	obtained on different architectures
	
	You can create a table of results in csv, html or latex format
	using the script './table.php'. By default you can select
	all cpus but you can also specify a list of cpus and the 
	compiler:
	
		> ./table.php  --compiler=gnu --format=latex 
		
	If you generate results for a new cpu not already present in the
	list, you need to fill the 'processors.txt' file by providing a
	new entry in the text file as follows:
	
		<name-of-cpu-from ./cpu_name.sh>|<brand>|Model|SubModel
	
	For example, for an Intel Core i5 7400 @ 3.00 GHz:
	
		Intel-Core-i5-7400-3_00GHz|Intel|i5|7400

---------------------------------------------------------------------	
3. VALIDITY TESTS
---------------------------------------------------------------------

 	Run the ./validity_test.php script from the directory of 
	the project. It will execute the program on different sizes
	of string to test if all functions provide the same result.

	You can also use make to run the test:
	
		> make validity
		
---------------------------------------------------------------------	
5. PERFORMANCE TESTS
---------------------------------------------------------------------

	Run the ./performance_test.php script from the directory of 
	the project. It will execute the program on different sizes
	of the strings and report their execution times.
	
	You can also use make to run the test:
	
		> make performance
		
	After executing the different methods on a set of sizes	
	two graphics in PDF format will be generated using gnuplot:
	
	- a first one with all implemented functions
	- a second one with the best (or most efficient) functions


