Lesson N.2 of July 15, 2014¶
File example6.cc
1/*
2 Few example using template (preliminari part)
3*/
4
5#include <iostream>
6#include <cmath>
7using namespace std ; // for the moment magic ``keyword''
8
9//static // local function
10unsigned // return the index of the minimum
11findMinimum( int a[], unsigned size ) {
12 unsigned imin = 0 ;
13 for ( unsigned i = 1 ; i < size ; ++i )
14 if ( a[i] < a[imin] ) imin = i ;
15 return imin ;
16}
17
18//static // local function
19unsigned // return the index of the minimum
20findMinimum( long int a[], unsigned size ) {
21 unsigned imin = 0 ;
22 for ( unsigned i = 1 ; i < size ; ++i )
23 if ( a[i] < a[imin] ) imin = i ;
24 return imin ;
25}
26
27int
28main( /* no argument for the moment */ ) {
29 int a[] = {2,-3,1,2,-9,8} ; ;
30 unsigned ipos = findMinimum( a, sizeof(a)/sizeof(a[0]) ) ;
31 cout << "minimum is " << a[ipos] << " at position " << ipos << '\n' ;
32 return 0 ; // return 0 to the OS
33}
File example7.cc
1/*
2 Few example using template (preliminari part)
3*/
4
5#include <iostream>
6#include <cmath>
7#include <complex>
8
9using namespace std ; // for the moment magic ``keyword''
10
11template <typename T>
12unsigned // return the index of the minimum
13findMinimum( T a[], unsigned size ) ;
14
15// specialize the code for complex number
16template <typename T>
17unsigned // return the index of the minimum
18findMinimum( complex<T> a[], unsigned size ) ;
19
20// specialize the code for complex number
21template <>
22unsigned // return the index of the minimum
23findMinimum( complex<double> a[], unsigned size ) ;
24
25// specialize the code for complex number
26unsigned // return the index of the minimum
27findMinimum( complex<double> a[], unsigned size ) ;
28
29/*
30{
31 cout << "Calling version 4\n" ;
32 unsigned imin = 0 ;
33 for ( unsigned i = 1 ; i < size ; ++i )
34 if ( std::abs(a[i]) < std::abs(a[imin]) ) imin = i ;
35 return imin ;
36}
37*/
38
39int
40main( /* no argument for the moment */ ) {
41 double a[] = {2,-3,1,2,-9,8} ; ;
42 unsigned ipos = findMinimum( a, sizeof(a)/sizeof(a[0]) ) ;
43 cout << "minimum is " << a[ipos] << " at position " << ipos << '\n' ;
44
45 complex<double> b[] = { complex<double>(1,3),
46 complex<double>(0,1),
47 complex<double>(-2,0),
48 complex<double>(1,3),
49 complex<double>(1.2,0) } ;
50 ipos = findMinimum( b, sizeof(b)/sizeof(b[0]) ) ;
51 cout << "minimum is " << b[ipos] << " at position " << ipos << '\n' ;
52 return 0 ; // return 0 to the OS
53}
File example7b.cc
1/*
2 Few example using template (preliminari part)
3*/
4
5#include <iostream>
6#include <cmath>
7#include <complex>
8
9using namespace std ; // for the moment magic ``keyword''
10using namespace std ; // for the moment magic ``keyword''
11
12template <typename T>
13unsigned // return the index of the minimum
14findMinimum( T a[], unsigned size ) {
15 cout << "Calling version 1\n" ;
16 unsigned imin = 0 ;
17 for ( unsigned i = 1 ; i < size ; ++i )
18 if ( a[i] < a[imin] ) imin = i ;
19 return imin ;
20}
21
22// specialize the code for complex number
23template <typename T>
24unsigned // return the index of the minimum
25findMinimum( complex<T> a[], unsigned size ) {
26 cout << "Calling version 2\n" ;
27 unsigned imin = 0 ;
28 for ( unsigned i = 1 ; i < size ; ++i )
29 if ( std::abs(a[i]) < std::abs(a[imin]) ) imin = i ;
30 return imin ;
31}
32
33// specialize the code for complex number
34template <>
35unsigned // return the index of the minimum
36findMinimum( complex<double> a[], unsigned size ) {
37 cout << "Calling version 3\n" ;
38 unsigned imin = 0 ;
39 for ( unsigned i = 1 ; i < size ; ++i )
40 if ( std::abs(a[i]) < std::abs(a[imin]) ) imin = i ;
41 return imin ;
42}
43
44// specialize the code for complex number
45unsigned // return the index of the minimum
46findMinimum( complex<double> a[], unsigned size )
47{
48 cout << "Calling version 4\n" ;
49 unsigned imin = 0 ;
50 for ( unsigned i = 1 ; i < size ; ++i )
51 if ( std::abs(a[i]) < std::abs(a[imin]) ) imin = i ;
52 return imin ;
53}
54
55// explicit instantiation
56template unsigned findMinimum( complex<double> a[], unsigned size ) ;
57template unsigned findMinimum( double a[], unsigned size ) ;
58template unsigned findMinimum( int a[], unsigned size ) ;
59template unsigned findMinimum( float a[], unsigned size ) ;
60template unsigned findMinimum( short a[], unsigned size ) ;
Matrix matrix multiplication
File mm.hh
1/*
2 * Matrix Matrix multiplication routine
3 */
4
5#ifndef MM_HH
6#define MM_HH
7
8//
9// int : integer (normally of 4 bytes) signed int
10// unsigned : integer with no sign (normally of 4 bytes) unsigned int
11// long : integer (normally of 8 bytes) long int
12// unsigned long : nteger with no sign (normally of 8 bytes)
13// short : integer (normally of 2 bytes) signed short
14// unsigned short : integer with no sign (normally of 2 bytes)
15//
16
17void
18mm_print( double const A[], // `vector` pointing to the matrix A
19 unsigned ldA, // number of row of the allocated matrix A
20 unsigned n_row, // number of rows
21 unsigned n_col ) ; // number of columns ;
22
23void
24mm_standard( double const A[], // `vector` pointing to the matrix A
25 unsigned ldA, // number of row of the allocated matrix A
26 double const B[], // `vector` pointing to the matrix B
27 unsigned ldB, // number of row of the allocated matrix B
28 double C[], // `vector` pointing to the matrix C
29 unsigned ldC, // number of row of the allocated matrix C
30 unsigned n, // number of the rows of A
31 unsigned p, // number of the columns of A and rows of B
32 unsigned m // number of the columns of B
33 // the results is a matrix C of n rows and m columns
34
35 ) ;
36
37#endif
File mm_utils.cc
1/*
2 * Matrix Matrix multiplication routine
3 */
4
5#include <iostream>
6#include <iomanip>
7
8#include "mm.hh"
9#define A(I,J) A[(I)+(J)*ldA]
10
11using namespace std ;
12
13void
14mm_print( double const A[],
15 unsigned ldA,
16 unsigned n_row,
17 unsigned n_col ) {
18 for ( unsigned i = 0 ; i < n_row ; ++i ) {
19 cout << A(i,0) ;
20 for ( unsigned j = 1 ; j < n_col ; ++j )
21 cout << " " << setw(10) << A(i,j) ; // setw reserve 10 space for the next output
22 cout << '\n' ;
23 }
24}
File mm_standard.cc
1/*
2 Matrix Matrix multiplication routine
3
4 g++ -O3 -funroll-loops -sse2 -sse3 -sse3 -ssse3 -sse4.1 mm_check.cc mm_standard.cc TimeMeter.cc
5
6 5 x 5 average time 0.01
7 10 x 10 average time 0.004
8 20 x 20 average time 0.014
9 40 x 40 average time 0.099
10 80 x 80 average time 0.789
11 160 x 160 average time 8.526
12 320 x 320 average time 70.61
13 640 x 640 average time 981.838
14 1280 x 1280 average time 10938.1
15 2560 x 2560 average time 624531
16 Time Ratio [ 10/5] = 0.4
17 Time Ratio [ 20/10] = 3.5
18 Time Ratio [ 40/20] = 7.07143
19 Time Ratio [ 80/40] = 7.9697
20 Time Ratio [ 160/80] = 10.8061
21 Time Ratio [ 320/160] = 8.28173
22 Time Ratio [ 640/320] = 13.9051
23 Time Ratio [ 1280/640] = 11.1404
24 Time Ratio [ 2560/1280] = 57.0969
25*/
26
27#include "mm.hh"
28
29#define A(I,J) A[(I)+(J)*ldA]
30#define B(I,J) B[(I)+(J)*ldB]
31#define C(I,J) C[(I)+(J)*ldC]
32
33void
34mm_standard( double const A[],
35 unsigned ldA,
36 double const B[],
37 unsigned ldB,
38 double C[],
39 unsigned ldC,
40 unsigned n,
41 unsigned p,
42 unsigned m ) {
43 for ( unsigned i = 0 ; i < n ; ++i )
44 for ( unsigned j = 0 ; j < m ; ++j ) {
45 C(i,j) = 0 ; // C[i+j*ldC] ;
46 for ( unsigned k = 0 ; k < p ; ++k )
47 C(i,j) += A(i,k) * B(k,j) ;
48 }
49}
File mm_check.cc
1#include <iostream>
2#include <iomanip>
3#include <cstdlib> // near equivalent to <stdlib.h> for exit, rand, ...
4#include <cmath> // near equivalent to <math.h> for sin, cos, log, ..
5#include "mm.hh"
6
7#define A(I,J) A[(I)+(J)*ldA]
8#define B(I,J) B[(I)+(J)*ldB]
9#define C(I,J) C[(I)+(J)*ldC]
10
11using namespace std ;
12
13int
14main() {
15
16 double A[9] = { 1,2,3, // first column
17 4,5,6, // second column
18 7,8,9 } ; // third column
19 double B[] = { 1,2,0, // first column
20 0,0,1, // second column
21 1,2,1} ; // third column
22 double C[100] ;
23
24 cout << "Matrix A\n" ;
25 mm_print( A, 3, 3, 3 ) ;
26 cout << "Matrix B\n" ;
27 mm_print( B, 3, 3, 3 ) ;
28
29 mm_standard( A, 3,
30 B, 3,
31 C, 3,
32 3, 3, 3 ) ;
33
34 cout << "Matrix C = A*B\n" ;
35 mm_print( C, 3, 3, 3 ) ;
36
37}
File TimeMeter.hh
1/*--------------------------------------------------------------------------*\
2 | |
3 | Copyright (C) 2014 |
4 | |
5 | , __ , __ |
6 | /|/ \ /|/ \ |
7 | | __/ _ ,_ | __/ _ ,_ |
8 | | \|/ / | | | | \|/ / | | | |
9 | |(__/|__/ |_/ \_/|/|(__/|__/ |_/ \_/|/ |
10 | /| /| |
11 | \| \| |
12 | |
13 | Enrico Bertolazzi |
14 | Dipartimento di Ingegneria Indutriale |
15 | Universita` degli Studi di Trento |
16 | Via Sommarive 9, I-38123, Povo, Trento |
17 | email: enrico.bertolazzi@unitn.it |
18 | |
19 | version: 0.1 |
20 | |
21\*--------------------------------------------------------------------------*/
22
23// to avoid double inclusion
24#ifndef TIME_METER_HH
25#define TIME_METER_HH
26
27// prototype of the function
28bool
29getTime( long & sec, long & usec ) ; // return seconds and microseconds from January 1, 1970
30
31void
32timeDifference( long from_sec, long from_usec,
33 long to_sec, long to_usec,
34 long & sec, long & usec ) ;
35
36#endif
File TimeMeter.cc
1/*--------------------------------------------------------------------------*\
2 | |
3 | Copyright (C) 2014 |
4 | |
5 | , __ , __ |
6 | /|/ \ /|/ \ |
7 | | __/ _ ,_ | __/ _ ,_ |
8 | | \|/ / | | | | \|/ / | | | |
9 | |(__/|__/ |_/ \_/|/|(__/|__/ |_/ \_/|/ |
10 | /| /| |
11 | \| \| |
12 | |
13 | Enrico Bertolazzi |
14 | Dipartimento di Ingegneria Indutriale |
15 | Universita` degli Studi di Trento |
16 | Via Sommarive 9, I-38123, Povo, Trento |
17 | email: enrico.bertolazzi@unitn.it |
18 | |
19 | version: 0.1 |
20 | |
21\*--------------------------------------------------------------------------*/
22
23#include "TimeMeter.hh"
24
25/*
26// _ _____ _
27// __ _ ___| ||_ _(_)_ __ ___ ___
28// / _` |/ _ \ __|| | | | '_ ` _ \ / _ \
29// | (_| | __/ |_ | | | | | | | | | __/
30// \__, |\___|\__||_| |_|_| |_| |_|\___|
31// |___/
32*/
33
34#ifdef WIN32
35 #ifndef WIN32_LEAN_AND_MEAN
36 #define WIN32_LEAN_AND_MEAN
37 #endif
38 #include <windows.h>
39 bool
40 getTime( long & sec, long & usec ) {
41 FILETIME ft ;
42 GetSystemTimeAsFileTime( &ft ) ;
43
44 // FILETIME To UNIX Time
45 unsigned __int64 u_sec = ft . dwHighDateTime ;
46 u_sec <<= 32 ;
47 u_sec |= ft . dwLowDateTime ;
48 u_sec -= 116444736000000000ULL ;
49 u_sec /= 10ULL ;
50
51 sec = long( u_sec / 1000000L ) ;
52 usec = long( u_sec % 1000000L ) ;
53 return true ;
54 }
55#else
56 #include <sys/time.h>
57 bool
58 getTime( long & sec, long & usec ) {
59 struct timeval now ;
60 bool ok = gettimeofday(&now, NULL) == 0 ;
61 if ( ok ) {
62 sec = now . tv_sec;
63 usec = now . tv_usec;
64 } else {
65 sec = usec = 0 ;
66 }
67 return ok ;
68 }
69#endif
70
71void
72timeDifference( long from_sec, long from_usec,
73 long to_sec, long to_usec,
74 long & sec, long & usec ) {
75 sec = to_sec - from_sec ;
76 usec = to_usec - from_usec ;
77 while ( usec < 0 ) { --sec ; usec += 1000000L ; }
78 while ( usec > 1000000L ) { ++sec ; usec -= 1000000L ; }
79}
80
81// EOF TimeMeter.cc
File mm_check_time.cc
1#include <iostream>
2#include <iomanip>
3#include <cstdlib> // near equivalent to <stdlib.h> for exit, rand, ...
4#include <cmath> // near equivalent to <math.h> for sin, cos, log, ..
5
6#include "mm.hh"
7#include "TimeMeter.hh"
8
9
10using namespace std ;
11
12//
13// Fill with random value matric A (n x m)
14//
15static // routine visible only in "this file"
16void
17fillRandom( double A[], unsigned ldA, unsigned n, unsigned m ) {
18 #define A(I,J) A[(I)+(J)*ldA]
19 for ( unsigned i = 0 ; i < n ; ++i )
20 for ( unsigned j = 0 ; j < m ; ++j )
21 A(i,j) = rand()-rand() ; // IS NOT 0!
22 #undef A
23}
24
25#define NREPEAT 2
26#define n 640
27
28int
29main() {
30
31 // for timing
32 long from_sec, from_usec ;
33 long to_sec, to_usec ;
34 long sec, usec ;
35
36 // declare and allocate matrices A, B and C
37 static double A[n*n] ;
38 static double B[n*n] ;
39 static double C[n*n] ;
40
41 // fill matrices A, B with random numbers
42 fillRandom( A, n, n, n ) ;
43 fillRandom( B, n, n, n ) ;
44
45 getTime( from_sec, from_usec ) ;
46 for ( int kk = 0 ; kk < NREPEAT ; ++kk ) {
47 mm_standard( A, n, B, n, C, n, n, n, n ) ;
48 mm_standard( A, n, B, n, C, n, n, n, n ) ;
49 mm_standard( A, n, B, n, C, n, n, n, n ) ;
50 mm_standard( A, n, B, n, C, n, n, n, n ) ;
51 mm_standard( A, n, B, n, C, n, n, n, n ) ;
52 mm_standard( A, n, B, n, C, n, n, n, n ) ;
53 mm_standard( A, n, B, n, C, n, n, n, n ) ;
54 mm_standard( A, n, B, n, C, n, n, n, n ) ;
55 mm_standard( A, n, B, n, C, n, n, n, n ) ;
56 mm_standard( A, n, B, n, C, n, n, n, n ) ;
57 }
58 getTime( to_sec, to_usec ) ;
59
60 timeDifference( from_sec, from_usec, to_sec, to_usec, sec, usec ) ;
61
62 double elapsed = sec+1E-6*usec ;
63
64 cout << "Elapsed time = " << elapsed/NREPEAT/10 << " seconds\n" ;
65
66 return 0 ;
67}
All files in a zip file