//This program is intended to demonstrate simple serial programming where a vectors element gets modified serially. // #include <iostream> #include <vector> #include <cmath> #include <chrono> using std::cout; using std::endl; using std::vector; void increase_magnitude(float *starting_address,unsigned int size_vec, float mag_multiplyer) { //the variable *starting_address is a pointer which will point to (or contain address of), the first element of the array. for (int i=0;i<size_vec;i++) //2 instructions per loop for updating i, and checking i<size { //let us multiply the whole vector by 2 //since we have address of first element of vector, we can take its value by use of * *starting_address=*starting_address * mag_multiplyer; //4 instructions //now we shall increase its address by 1. starting_address+=1; //2 instructions (add sum, and update sum) } //in total loop shall have 8 instructions per loop, so time taken shall be (size/clockspeed)*instructions per loop //in this way at the same memory location we will have modified the vector. } double magnitude_finder(float *starting_address_vec,unsigned int size) { //This function will return the magnitude of the vector. double sum=0.0; for (int i=0;i<size;i++) //2 instructions per loop for updating i, and checking i<size { /* sum+=pow((*starting_address_vec),2); //power function is slow (10 times)*/ sum+=(*starting_address_vec)*(*starting_address_vec); //5 instructions starting_address_vec+=1; //2 instructions } //9 instructions per loop return pow(sum,0.5); } int main(int argc, char *argv[]) { auto time_0 = std::chrono::high_resolution_clock::now(); unsigned int N=1<<31; //the number implies 31 zeroes in front of 1. So it is 2^31. auto time_1 = std::chrono::high_resolution_clock::now(); float *vec=new float[N]; //dynamics_array allocation does not take any time comparable to stack memory //let us fill the vector with N natural numbers(1,2,.......N). auto time_2 = std::chrono::high_resolution_clock::now(); auto elapsed_time_1 = std::chrono::duration_cast<std::chrono::microseconds>(time_2 - time_1).count() / 1e6; auto elapsed_time_storing_N = std::chrono::duration_cast<std::chrono::microseconds>(time_1 - time_1).count() / 1e6; for (int i=0;i<N;i++) { vec[i]=i; } auto time_3 = std::chrono::high_resolution_clock::now(); auto elapsed_time_assigning_values = std::chrono::duration_cast<std::chrono::microseconds>(time_3 - time_2).count() / 1e6; /* cout<<vec[0]<<vec[1]<<vec[2]<<vec[3]<<endl; */ //let us define a pointer to integer vector float *ptr_to_vec=&vec[0]; //giving address of first element. Or we can just write: //we shall modify the vector by multiply it with some real number. //Real numbers are stored in float data types(require 4byte per real number) and double data types(8bytes). float multiplier=4.0; //Let us find the magnitude before changing the vector, double mag_before=magnitude_finder(ptr_to_vec,N); auto time_4 = std::chrono::high_resolution_clock::now(); auto elapsed_time_mag1 = std::chrono::duration_cast<std::chrono::microseconds>(time_4 - time_3).count() / 1e6; increase_magnitude(ptr_to_vec,N,multiplier); auto time_5 = std::chrono::high_resolution_clock::now(); auto elapsed_time_modify_mag = std::chrono::duration_cast<std::chrono::microseconds>(time_5 - time_4).count() / 1e6; double mag_after=magnitude_finder(ptr_to_vec,N); auto time_6 = std::chrono::high_resolution_clock::now(); auto elapsed_time_mag2 = std::chrono::duration_cast<std::chrono::microseconds>(time_6 - time_5).count() / 1e6; double ratio_of_magnitudes=mag_after/mag_before; printf("Value of magnitude before multiplying the vector is %0.f \n",mag_before); printf("Value of magnitude after multiplying the vector is %0.f \n",mag_after); cout<<"the final vector has magnitude "<<ratio_of_magnitudes<<" times the earlier one"<<endl<<"which should be equal to the multiplier (which is: "<<multiplier<<")"<<endl; cout<<"the time to assign N: "<<elapsed_time_storing_N<<" seconds"<<endl; cout<<"the time to declare vector of N with doubles data type : "<<elapsed_time_1<<" seconds"<<endl; cout<<"the time to assign vector: "<<elapsed_time_assigning_values<<" seconds"<<endl; cout<<"the time to find magnitude of vector_in: "<<elapsed_time_mag1<<" seconds"<<endl; cout<<"the time to modify the vector_in: "<<elapsed_time_modify_mag<<" seconds"<<endl; cout<<"the time to calculate magnitude of modified vector_in: "<<elapsed_time_mag2<<" seconds"<<endl; cout<<" The total time shall be :"<<elapsed_time_1+elapsed_time_assigning_values+elapsed_time_mag1+elapsed_time_modify_mag+elapsed_time_mag2<<" seconds"<<endl; delete[] vec; return 0; }
Output:
```
Value of magnitude before multiplying the vector is 57455839005566
Value of magnitude after multiplying the vector is 229823356022263
the final vector has magnitude 4 times the earlier one
which should be equal to the multiplier (which is: 4)
the time to assign N: 0 seconds
the time to declare vector of N with doubles data type : 9e-06 seconds
the time to assign vector: 7.3436 seconds
the time to find magnitude of vector_in: 5.81952 seconds
the time to modify the vector_in: 4.70668 seconds
the time to calculate magnitude of modified vector_in: 5.79976 seconds
The total time shall be :23.6696 seconds
real 0m23.983s
user 0m20.541s
sys 0m3.373s
```
Remarks: I totally forgot that the answer I am printing is might be wrong.