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


---------------------------------------------------------------------
1. DESCRIPTION
---------------------------------------------------------------------
Comparison of different implementations of a function that counts
the number of vowels (a,e,i,o,u,y) in a string with lower case
characters

The code of the function is the following :

/**
 * default method to count number of vowels in a string
 * using if then else
 * @param s string
 * @param size size of string
 * @param v array that contains the number of occurrences of
 *        each vowel
 */
void count_if(u8 *s, u32 size, u32 v[6]) {
	for (u32 i=0; i<size; ++i) {
		if (s[i] == 'a') {
			++v[0];
		} else if (s[i] == 'e') {
			++v[1];
		} else if (s[i] == 'i') {
			++v[2];
		} else if (s[i] == 'o') {
			++v[3];
		} else if (s[i] == 'u') {
			++v[4];
		} else if (s[i] == 'y') {
			++v[5];
		}  
	}
}

The different functions that are implemented are the following :
- 1 count_if : reference function, compiled with -O3
- 2 count_switch : use of switch instead of if, compiled with -O3
- 3 count_letters : count all letters, compiled with -O3
- 4 count_sse2 : assembly version that only counts vowels with SSE2
- 5 count_avx  : assembly version that only counts vowels with AVX
- 6 count_avx2 : assembly version that only counts vowels with AVX2
- 7 count_avx2_u2 : assembly version that only counts vowels with AVX2
	 	and loop unrollling of 2


---------------------------------------------------------------------
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


