Lesson N.3 of July 16, 2014¶
Pointers
File example8.cc
:open:
1/*
2 Some examples with pointers
3
4
5*/
6
7#include <iostream>
8#include <iomanip>
9
10using namespace std ;
11
12int
13main() {
14
15 short int vec[] = {1,2,3,4,5,6} ;
16
17 cout << "Print the vector:\n" ;
18 for ( int i = 0 ; i < 6 ; ++i )
19 cout << "vec[" << i << "] = " << vec[i] << '\n' ;
20
21 short int * pvec ; // pointer to an integer
22
23 pvec = & vec[3] ; // pvec now "point" to the 4th element of the vector
24 cout << "vec[3] = " << vec[3] << '\n' ;
25 cout << "*pvec = " << *pvec << '\n' ;
26
27 cout << "modify *pvec = 123\n" ;
28 *pvec = 123 ;
29
30 cout << "Print the vector:\n" ;
31 for ( int i = 0 ; i < 6 ; ++i )
32 cout << "vec[" << i << "] = " << vec[i] << '\n' ;
33
34 cout << "Loop using pointer pvec...\n" ;
35 int i ;
36 for ( i = 0, pvec = vec ; i < 6 ; ++i, ++pvec )
37 *pvec = 2 ;
38
39 cout << "Print the vector:\n" ;
40 for ( int i = 0 ; i < 6 ; ++i )
41 cout << "vec[" << i << "] = " << vec[i] << '\n' ;
42
43 cout << "Better Loop using pointer pvec...\n" ;
44 for ( pvec = vec ; pvec < vec+6 ; ++pvec )
45 { cout << "Modify at address: " << pvec
46 << " the value " << *pvec << '\n' ;
47 *pvec = 3 ; }
48
49 cout << "Print the vector:\n" ;
50 for ( int i = 0 ; i < 6 ; ++i )
51 cout << "vec[" << i << "] = " << vec[i] << '\n' ;
52
53
54 return 0 ;
55}
Unsane C-like vector
File mv.hh
:open:
1/*
2
3 Simple C-like dynamic vectors/matrices
4
5 use doble, no typedef no template
6
7*/
8
9#include <cstddef>
10
11// if C++ < C++11 define nullptr
12#if __cplusplus <= 199711L
13 #include <cstdlib>
14 #ifndef nullptr
15 #include <cstddef>
16 #define nullptr NULL
17 #endif
18#endif
19
20// define a vector as a struct with the size of the vector
21// and a pointer to its values
22
23struct Vec {
24 int size ;
25 double * values ;
26} ;
27
28void Initialize( struct Vec & vec ) ;
29void Allocate( struct Vec & vec, int size ) ;
30void Free( struct Vec & vec ) ;
File mv.cc
:open:
1#include "mv.hh"
2
3// initialize structure to a vector of size 0
4void
5Initialize( struct Vec & vec ) {
6 vec.size = 0 ;
7 vec.values = nullptr ;
8}
9
10// alocate a vector to teh size: size
11void
12Allocate( struct Vec & vec, int size ) {
13 vec.size = size ;
14 // check if alreay allocated
15 if ( vec.values != nullptr ) delete [] vec.values ;
16 vec.values = new double[size] ;
17}
18
19void
20Free( struct Vec & vec ) {
21 // check if alreay de-allocated
22 if ( vec.values != nullptr ) delete [] vec.values ;
23 vec.size = 0 ;
24}
File mv_test.cc
:open:
1#include "mv.hh"
2
3int
4main() {
5 struct Vec a, b, c ;
6 double pippo = 1234 ;
7 c.values = &pippo ; // force error....
8 Initialize(a) ;
9 Initialize(b) ;
10
11 Allocate( a, 100 ) ;
12 Allocate( b, 100 ) ;
13 Allocate( c, 100 ) ;
14
15 Free( a ) ;
16 Free( b ) ;
17 Free( c ) ;
18
19}
Unsane C-like vector/matrix functions
File mv.hh
:open:
1/*
2
3 Simple C-like dynamic vectors/matrices
4
5 use doble, no typedef no template
6
7*/
8
9#include <cstddef>
10
11// if C++ < C++11 define nullptr
12#if __cplusplus <= 199711L
13 #include <cstdlib>
14 #ifndef nullptr
15 #include <cstddef>
16 #define nullptr NULL
17 #endif
18#endif
19
20// define a vector as a struct with the size of the vector
21// and a pointer to its values
22
23struct Vec {
24 int size ;
25 double * values ;
26} ;
27
28struct Mat {
29 int nrow, ncol ;
30 double * memory_block ; // allocated memory for the matrix
31 double ** values ; // pointer to the rows of the matrix
32} ;
33
34void Initialize( struct Vec & vec ) ;
35void Allocate( struct Vec & vec, int size ) ;
36void Fill( struct Vec & mat, double val ) ;
37void Free( struct Vec & vec ) ;
38
39void Initialize( struct Mat & mat ) ;
40void Allocate( struct Mat & mat, int nrow, int ncol ) ;
41void AllocateAndInitializeRandom( struct Mat & mat, int nrow, int ncol ) ;
42void Fill( struct Mat & mat, double val ) ;
43void Free( struct Mat & mat ) ;
44
45void
46Mat_x_Vec( struct Mat const & mat, // ensure the compiler that mat is not modified inside...
47 struct Vec const & vec,
48 struct Vec & res ) ;
49
50void
51Mat_x_Mat_123( struct Mat const & A,
52 struct Mat const & B,
53 struct Mat & C ) ;
54void
55Mat_x_Mat_132( struct Mat const & A,
56 struct Mat const & B,
57 struct Mat & C ) ;
58void
59Mat_x_Mat_213( struct Mat const & A,
60 struct Mat const & B,
61 struct Mat & C ) ;
62void
63Mat_x_Mat_231( struct Mat const & A,
64 struct Mat const & B,
65 struct Mat & C ) ;
66void
67Mat_x_Mat_312( struct Mat const & A,
68 struct Mat const & B,
69 struct Mat & C ) ;
70void
71Mat_x_Mat_321( struct Mat const & A,
72 struct Mat const & B,
73 struct Mat & C ) ;
74
75void
76Mat_x_Mat_with_tiling( struct Mat const & A,
77 struct Mat const & B,
78 struct Mat & C,
79 int tsize ) ;
File mv_vec.cc
:open:
1#include "mv.hh"
2
3// initialize structure to a vector of size 0
4void
5Initialize( struct Vec & vec ) {
6 vec.size = 0 ;
7 vec.values = nullptr ;
8}
9
10// alocate a vector to teh size: size
11void
12Allocate( struct Vec & vec, int size ) {
13 vec.size = size ;
14 // check if alreay allocated
15 if ( vec.values != nullptr ) delete [] vec.values ;
16 vec.values = new double[size] ;
17}
18
19void
20Fill( struct Vec & vec, double val ) {
21 for ( int i = 0 ; i < vec.size ; ++i )
22 vec.values[i] = val ;
23}
24
25void
26Free( struct Vec & vec ) {
27 // check if alreay de-allocated
28 if ( vec.values != nullptr ) delete [] vec.values ;
29 vec.size = 0 ;
30}
File mv_mat.cc
:open:
1#include "mv.hh"
2
3#include <iostream>
4#include <stdlib.h> // for rand() function
5
6using namespace std ;
7
8// initialize structure to a matrix of size 0 x 0
9void
10Initialize( struct Mat & mat ) {
11 mat.nrow = 0 ;
12 mat.ncol = 0 ;
13 mat.memory_block = nullptr ;
14 mat.values = nullptr ;
15}
16
17// alocate a matrix to the size: nrow x ncol
18void
19Allocate( struct Mat & mat, int nrow, int ncol ) {
20
21 if ( mat.nrow == nrow && mat.ncol == ncol ) return ; // nothing to do!
22
23 mat.nrow = nrow ;
24 mat.ncol = ncol ;
25
26 if ( mat.memory_block != nullptr ) delete [] mat.memory_block ;
27 mat.memory_block = new double [nrow*ncol] ;
28
29 if ( mat.values != nullptr ) delete [] mat.values ;
30 mat.values = new double* [nrow] ;
31
32 // initialize the pointer of pointer
33 for ( int i = 0 ; i < nrow ; ++i )
34 mat.values[i] = mat.memory_block + i * ncol ;
35}
36
37void
38AllocateAndInitializeRandom( struct Mat & mat, int nrow, int ncol ) {
39 Allocate( mat, nrow, ncol ) ;
40 for ( int i = 0 ; i < mat.nrow ; ++i )
41 for ( int j = 0 ; j < mat.ncol ; ++j )
42 mat.values[i][j] = rand() - rand() ;
43}
44
45void
46Fill( struct Mat & mat, double val ) {
47 for ( int i = 0 ; i < mat.nrow ; ++i )
48 for ( int j = 0 ; j < mat.ncol ; ++j )
49 mat.values[i][j] = val ;
50}
51
52void
53Mat_x_Vec( struct Mat const & mat, // ensure the compiler that mat is not modified inside...
54 struct Vec const & vec,
55 struct Vec & res ) {
56 // check matrix vector compatibility
57 if ( mat.ncol != vec.size ) {
58 cerr << "Mat_x_Vec, incompatible dimensions\n" ;
59 exit(0) ;
60 }
61 if ( res.size != mat.nrow ) Allocate( res, mat.nrow ) ;
62 for ( int i = 0 ; i < mat.nrow ; ++i ) {
63 res.values[i] = 0 ;
64 for ( int j = 0 ; j < mat.ncol ; ++i )
65 res.values[i] += mat.values[i][j]*vec.values[j] ;
66 }
67}
68
69void
70Mat_x_Mat_123( struct Mat const & A,
71 struct Mat const & B,
72 struct Mat & C ) {
73 // check compatibility
74 if ( A.ncol != B.nrow ) {
75 cerr << "Mat_x_Mat_123, incompatible dimensions\n" ;
76 exit(0) ;
77 }
78
79 // initialize matrix C
80 Allocate( C, A.nrow, B.ncol ) ;
81
82 // set to 0
83 Fill( C, 0 ) ; // 0 int --> convertex 0 double
84
85 for ( int i = 0 ; i < A.nrow ; ++i ) // 1
86 for ( int j = 0 ; j < B.ncol ; ++j ) // 2
87 for ( int k = 0 ; k < A.ncol ; ++k ) // 3
88 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
89}
90
91void
92Mat_x_Mat_132( struct Mat const & A,
93 struct Mat const & B,
94 struct Mat & C ) {
95 // check compatibility
96 if ( A.ncol != B.nrow ) {
97 cerr << "Mat_x_Mat_132, incompatible dimensions\n" ;
98 exit(0) ;
99 }
100
101 // initialize matrix C
102 Allocate( C, A.nrow, B.ncol ) ;
103
104 // set to 0
105 Fill( C, 0 ) ; // 0 int --> convertex 0 double
106
107 for ( int i = 0 ; i < A.nrow ; ++i ) // 1
108 for ( int k = 0 ; k < A.ncol ; ++k ) // 3
109 for ( int j = 0 ; j < B.ncol ; ++j ) // 2
110 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
111}
112
113void
114Mat_x_Mat_213( struct Mat const & A,
115 struct Mat const & B,
116 struct Mat & C ) {
117 // check compatibility
118 if ( A.ncol != B.nrow ) {
119 cerr << "Mat_x_Mat_213, incompatible dimensions\n" ;
120 exit(0) ;
121 }
122
123 // initialize matrix C
124 Allocate( C, A.nrow, B.ncol ) ;
125
126 // set to 0
127 Fill( C, 0 ) ; // 0 int --> convertex 0 double
128
129 for ( int j = 0 ; j < B.ncol ; ++j ) // 2
130 for ( int i = 0 ; i < A.nrow ; ++i ) // 1
131 for ( int k = 0 ; k < A.ncol ; ++k ) // 3
132 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
133}
134
135void
136Mat_x_Mat_231( struct Mat const & A,
137 struct Mat const & B,
138 struct Mat & C ) {
139 // check compatibility
140 if ( A.ncol != B.nrow ) {
141 cerr << "Mat_x_Mat_231, incompatible dimensions\n" ;
142 exit(0) ;
143 }
144
145 // initialize matrix C
146 Allocate( C, A.nrow, B.ncol ) ;
147
148 // set to 0
149 Fill( C, 0 ) ; // 0 int --> convertex 0 double
150
151 for ( int j = 0 ; j < B.ncol ; ++j ) // 2
152 for ( int k = 0 ; k < A.ncol ; ++k ) // 3
153 for ( int i = 0 ; i < A.nrow ; ++i ) // 1
154 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
155}
156
157void
158Mat_x_Mat_312( struct Mat const & A,
159 struct Mat const & B,
160 struct Mat & C ) {
161 // check compatibility
162 if ( A.ncol != B.nrow ) {
163 cerr << "Mat_x_Mat_312, incompatible dimensions\n" ;
164 exit(0) ;
165 }
166
167 // initialize matrix C
168 Allocate( C, A.nrow, B.ncol ) ;
169
170 // set to 0
171 Fill( C, 0 ) ; // 0 int --> convertex 0 double
172
173 for ( int k = 0 ; k < A.ncol ; ++k ) // 3
174 for ( int i = 0 ; i < A.nrow ; ++i ) // 1
175 for ( int j = 0 ; j < B.ncol ; ++j ) // 2
176 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
177}
178
179void
180Mat_x_Mat_321( struct Mat const & A,
181 struct Mat const & B,
182 struct Mat & C ) {
183 // check compatibility
184 if ( A.ncol != B.nrow ) {
185 cerr << "Mat_x_Mat_321, incompatible dimensions\n" ;
186 exit(0) ;
187 }
188
189 // initialize matrix C
190 Allocate( C, A.nrow, B.ncol ) ;
191
192 // set to 0
193 Fill( C, 0 ) ; // 0 int --> convertex 0 double
194
195 for ( int k = 0 ; k < A.ncol ; ++k ) // 3
196 for ( int j = 0 ; j < B.ncol ; ++j ) // 2
197 for ( int i = 0 ; i < A.nrow ; ++i ) // 1
198 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
199}
200
201void
202Mat_x_Mat_with_tiling( struct Mat const & A,
203 struct Mat const & B,
204 struct Mat & C,
205 int tsize ) {
206 // check compatibility
207 if ( A.ncol != B.nrow ) {
208 cerr << "Mat_x_Mat_321, incompatible dimensions\n" ;
209 exit(0) ;
210 }
211
212 // initialize matrix C
213 Allocate( C, A.nrow, B.ncol ) ;
214
215 // set to 0
216 Fill( C, 0 ) ; // 0 int --> convertex 0 double
217
218 for ( int ii = 0 ; ii < A.nrow ; ii += tsize ) { // 1
219 int ii_max = std::min(ii + tsize, A.nrow) ;
220 for ( int kk = 0 ; kk < A.ncol ; kk += tsize ) { // 3
221 int kk_max = std::min(kk + tsize, A.ncol) ;
222 for ( int jj = 0 ; jj < B.ncol ; jj += tsize ) { // 2
223 int jj_max = std::min(jj + tsize, B.ncol) ;
224 for ( int i = ii ; i < ii_max ; ++i ) // 1
225 for ( int k = kk ; k < kk_max ; ++k ) // 3
226 for ( int j = jj ; j < jj_max ; ++j ) // 2
227 C.values[i][j] += A.values[i][k]*B.values[k][j] ;
228 }
229 }
230 }
231}
232
233void
234Free( struct Mat & mat ) {
235 // check if alreay de-allocated
236 if ( mat.memory_block != nullptr ) delete [] mat.memory_block ;
237 if ( mat.values != nullptr ) delete [] mat.values ;
238 mat.nrow = 0 ;
239 mat.ncol = 0 ;
240}
File mv_test.cc
:open:
1#include "mv.hh"
2#include "TimeMeter.hh"
3#include <iostream>
4
5using namespace std ;
6
7#define TEST(MM) \
8 timeStart() ; \
9 for ( int i = 0 ; i < NLOOP ; ++i ) { \
10 MM( A, B, C ) ; \
11 MM( C, B, A ) ; \
12 MM( A, B, C ) ; \
13 MM( C, B, A ) ; \
14 MM( A, B, C ) ; \
15 MM( C, B, A ) ; \
16 MM( A, B, C ) ; \
17 MM( C, B, A ) ; \
18 MM( A, B, C ) ; \
19 MM( C, B, A ) ; \
20 } \
21 elapsed = timeStop() ; \
22 cout << #MM << " time = " << elapsed/(10*NLOOP) << '\n'
23
24#define TESTT(TS) \
25 timeStart() ; \
26 for ( int i = 0 ; i < NLOOP ; ++i ) { \
27 Mat_x_Mat_with_tiling( A, B, C, TS ) ; \
28 Mat_x_Mat_with_tiling( C, B, A, TS ) ; \
29 Mat_x_Mat_with_tiling( A, B, C, TS ) ; \
30 Mat_x_Mat_with_tiling( C, B, A, TS ) ; \
31 Mat_x_Mat_with_tiling( A, B, C, TS ) ; \
32 Mat_x_Mat_with_tiling( C, B, A, TS ) ; \
33 Mat_x_Mat_with_tiling( A, B, C, TS ) ; \
34 Mat_x_Mat_with_tiling( C, B, A, TS ) ; \
35 Mat_x_Mat_with_tiling( A, B, C, TS ) ; \
36 Mat_x_Mat_with_tiling( C, B, A, TS ) ; \
37 } \
38 elapsed = timeStop() ; \
39 cout << "Mat_x_Mat_with_tiling(" << TS << ") time = " << elapsed/(10*NLOOP) << '\n'
40
41int
42main() {
43 struct Vec a, b, c ;
44 struct Mat A, B, C ;
45
46
47 Initialize(a) ;
48 Initialize(b) ;
49 Initialize(c) ;
50
51 Initialize(A) ;
52 Initialize(B) ;
53 Initialize(C) ;
54
55 Allocate( a, 100 ) ;
56 Allocate( b, 100 ) ;
57 Allocate( c, 100 ) ;
58
59 int N = 500 ;
60
61 AllocateAndInitializeRandom( A, N, N ) ;
62 AllocateAndInitializeRandom( B, N, N ) ;
63 Allocate( C, N, N ) ;
64
65 int NLOOP = 2 ;
66
67 timeStart() ;
68 for ( int i = 0 ; i < NLOOP ; ++i ) {
69 Mat_x_Mat_123( A, B, C ) ;
70 Mat_x_Mat_123( C, B, A ) ;
71 Mat_x_Mat_123( A, B, C ) ;
72 Mat_x_Mat_123( C, B, A ) ;
73 Mat_x_Mat_123( A, B, C ) ;
74 Mat_x_Mat_123( C, B, A ) ;
75 Mat_x_Mat_123( A, B, C ) ;
76 Mat_x_Mat_123( C, B, A ) ;
77 Mat_x_Mat_123( A, B, C ) ;
78 Mat_x_Mat_123( C, B, A ) ;
79 }
80 double elapsed = timeStop() ;
81 cout << "Mat_x_Mat_123 time = " << elapsed/(10*NLOOP) << '\n' ;
82
83 TEST(Mat_x_Mat_132) ;
84 TEST(Mat_x_Mat_213) ;
85 TEST(Mat_x_Mat_231) ;
86 TEST(Mat_x_Mat_312) ;
87 TEST(Mat_x_Mat_321) ;
88
89 TESTT( 10 ) ;
90 TESTT( 20 ) ;
91 TESTT( 40 ) ;
92 TESTT( 80 ) ;
93 TESTT( 120 ) ;
94 TESTT( 160 ) ;
95
96 Free( a ) ;
97 Free( b ) ;
98 Free( c ) ;
99
100 Free( A ) ;
101 Free( B ) ;
102 Free( C ) ;
103
104
105
106}
File TimeMeter.hh
:open:
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
36static long from_sec, from_usec ;
37
38inline
39bool
40timeStart() {
41 return getTime( from_sec, from_usec ) ;
42}
43
44inline
45double
46timeStop() {
47 long to_sec, to_usec, sec, usec;
48 getTime( to_sec, to_usec ) ;
49 timeDifference( from_sec, from_usec, to_sec, to_usec, sec, usec ) ;
50 return sec+1E-6*usec ;
51}
52
53#endif
File TimeMeter.cc
:open:
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
All files in a zip file<BR>