Calculate time taken to execute a C Program Code? - c

I need to calculate the time that is taken for various Sorting Algorithms in C
I am checking the time taken to sort 100,200,300,400 and 500 elements.
Surprisingly, the time taken to sort them seems to be the same!
Whats wrong in the code that I am getting the same time 0.00000 which is also absurd that it takes 0 seconds to sort the numbers.
Whats wrong in the code that I am getting such results?
What changes must be made to the Code that I get accurate time taken ( in Seconds) for sorting the numbers.
#include <stdio.h>
#include <time.h>
// Bubble Sort on 100 to 500 elements
int main()
{
int g;
//clock_t ti;
for(g=0;g<5;g++)
{
int n, i, j, swap;
clock_t ti;
time_t t;
srand((unsigned) time(&t));
//scanf("%d", &n);
n=100;
int array[n*(g+1)];
for (i = 0; i < n; i++)
array[i] = rand() % 10000;// Generating random numbers as array entries
//printf("%f \n",ti);
ti = clock();
for (i = 0 ; i < ( n - 1 ); i++)
{
for (j = 0 ; j < n - i - 1; j++)
{
if (array[j] > array[j+1])
{
swap = array[j];
array[j] = array[j+1];
array[j+1] = swap;
}
}
}
ti = clock() - ti;
double time_taken = ((double)ti)/CLOCKS_PER_SEC;
/*for ( i = 0 ; i < n ; i++ )
printf("%d \n ", array[i]);*/
printf("Time Taken to sort %d elements is %f\n",(g+1)*100,time_taken);
}
return 0;
}
The Output That I am getting is:
Time Taken to sort 100 elements is 0.000000
Time Taken to sort 200 elements is 0.000000
Time Taken to sort 300 elements is 0.000000
Time Taken to sort 400 elements is 0.000000
Time Taken to sort 500 elements is 0.000000

clock() might have too low of a resolution. Check your value for CLOCKS_PER_SEC.
clock_gettime() provides a high resolution timer.

I would prefer checking CPU cycles directly from CPU register instead of clock(). It's accurate and doesn't have overhead. How it's done depends on used CPU. See e.g. http://software.intel.com/en-us/forums/topic/300007
You must of course convert cycles to time if you actually need time. Like this (you must implement CPU specific get_cpu_cycles() according to your system/environment):
unsigned long begin = 0, end = 0, time = 0;
begin = get_cpu_cycles();
// Do what you like to measure
end = get_cpu_cycles();
unsigned long diff = end - begin;
const unsigned long cpu_speed = 1000000; // Core speed in kilo Hertz -> cpu_time in milliseconds.
double cpu_time = ((double) diff) / cpu_speed;
printf("Time: %.6f", cpu_time);
Please note that this is hard coded to have CPU speed as 1 GHz.

Related

how to measure the time taken to bubble sort 10 numbers

I am trying to measure the time it takes to bubble sort 10 large numbers. I put the numbers in an array of size 10. Then, I am bubble sorting the numbers 10 times and printing out the time taken for each time.
The problem is that all im getting is zeros for some reason!
Here is what i have in the main:
int n = sizeof(arr10)/sizeof(arr10[0]);
start=clock();
bubbleSort(arr10, n);
end=clock();
cpu_time_used = (double) (end - start) / CLOCKS_PER_SEC;
printf("Bubble Sort time= %f\n",cpu_time_used);
and here is the function of bubble sort:
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
That the result is zero is probaby because the resolution of clock() is too low. There are CLOCKS_PER_SEC ticks, and CLOCKS_PER_SEC is 1000. Your example probably runs in less than 1000th of a second (less than 1 millisecond).
Use %e format specifier to print the seconds. What is most likely happening is that the number is so small that %f just prints 0.
Anyway regardless of how you print it, the results are pretty much useless, as such a small time will not be relevant for measuring your algorithm, other noise in the OS will dominate.
Measuring the sort time of 10 numbers will never yield any significant value. Try with thousands and millions of numbers. And don't forget to compile with optimizations enabled.

Most efficient way to find all combinations of n choose 2

What is the most efficient way to find all combinations of n choose 2 for 2 <= n <= 100000?
For example, 5 choose 2 is
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
This is what I have so far for testing the worst case:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ITEMS 100000
void combinations(int[], int);
long long count = 0;
int main(void) {
int *arr = (int*) calloc(MAX_ITEMS, sizeof(int));
if (!arr) {
printf("Error allocating memory.");
exit(1);
}
int i, n = MAX_ITEMS;
for (i = 0; i < MAX_ITEMS; i++) {
arr[i] = i + 1;
}
clock_t start, diff;
int msec;
start = clock();
combinations(arr, n);
diff = clock() - start;
msec = diff * 1000 / CLOCKS_PER_SEC;
printf("\n\nTime taken %d seconds %d milliseconds", msec / 1000, msec % 1000);
printf("\n\nPairs = %lld\n", count);
return 0;
}
void combinations(int arr[], int n) {
int i, j, comb1, comb2, end = n - 1;
for (i = 0; i < end; i++) {
for (j = i + 1; j < n; j++) {
// simulate doing something with data at these indices
comb1 = arr[i];
comb2 = arr[j];
// printf("%d %d\n", arr[i], arr[j]);
count++;
}
}
}
OUTPUT
Time taken 28 seconds 799 milliseconds
Pairs = 4999950000
I could be mistaken but time complexity is O(n^2).
Is there a more efficient algorithm to handle the worst case?
There is no "best case" or "worst case". You need to generate exactly (n * (n - 1)) / 2 pairs, and your current program generates exactly those pairs and nothing else. Thus your program is optimal (in the algorithmic analysis sense) and is θ(n^2).
Some optimizations may be possible using various tricks (e.g. bitwise operations to go from one pair to the next, generating bulk pairs in one iteration, compiler optimizations, etc) but none would affect the time complexity of the algorithm.
Look at it this way, what if "n" was the number of pairs not the original size of the chose array. The complexity of your approach is O(n), not O (n^2). Notice you fill one index of the array for each iteration of the inner loop, regardless of your outter loop.
Given that, i dont think you can do significantly better. This is going to be a lower bound, you cant produce two pairs per step!! There for i would guess this is an optimal solution.
To continue -- if the output is n^2 the size of the input then your lower bound is always n^2 assuming you must touch every data point once. Which here you do.

C Threads program

I wrote a program based on the idea of Riemann's sum to find out the integral value. It uses several threads, but the performance of it (the algorithm), compared to sequential program i wrote later, is subpar. Algorithm-wise they are identical except the threads stuff, so the question is what's wrong with it? pthread_join is not the case, i assume, because if one thread will finish sooner than the other thread, that join wait on, it will simply skip it in the future. Is that correct? The free call is probably wrong and there is no error check upon creation of threads, i'm aware of it, i deleted it along the way of testing various stuff. Sorry for bad english and thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <time.h>
int counter = 0;
float sum = 0;
pthread_mutex_t mutx;
float function_res(float);
struct range {
float left_border;
int steps;
float step_range;
};
void *calcRespectiveRange(void *ranges) {
struct range *rangs = ranges;
float left_border = rangs->left_border;
int steps = rangs->steps;
float step_range = rangs->step_range;
free(rangs);
//printf("left: %f steps: %d step range: %f\n", left_border, steps, step_range);
int i;
float temp_sum = 0;
for(i = 0; i < steps; i++) {
temp_sum += step_range * function_res(left_border);
left_border += step_range;
}
sum += temp_sum;
pthread_exit(NULL);
}
int main() {
clock_t begin, end;
if(pthread_mutex_init(&mutx, NULL) != 0) {
printf("mutex error\n");
}
printf("enter range, amount of steps and threads: \n");
float left_border, right_border;
int steps_count;
int threads_amnt;
scanf("%f %f %d %d", &left_border, &right_border, &steps_count, &threads_amnt);
float step_range = (right_border - left_border) / steps_count;
int i;
pthread_t tid[threads_amnt];
float chunk = (right_border - left_border) / threads_amnt;
int steps_per_thread = steps_count / threads_amnt;
begin = clock();
for(i = 0; i < threads_amnt; i++) {
struct range *ranges;
ranges = malloc(sizeof(ranges));
ranges->left_border = i * chunk + left_border;
ranges->steps = steps_per_thread;
ranges->step_range = step_range;
pthread_create(&tid[i], NULL, calcRespectiveRange, (void*) ranges);
}
for(i = 0; i < threads_amnt; i++) {
pthread_join(tid[i], NULL);
}
end = clock();
pthread_mutex_destroy(&mutx);
printf("\n%f\n", sum);
double time_spent = (double) (end - begin) / CLOCKS_PER_SEC;
printf("Time spent: %lf\n", time_spent);
return(0);
}
float function_res(float lb) {
return(lb * lb + 4 * lb + 3);
}
Edit: in short - can it be improved to reduce execution time (with mutexes, for example)?
The execution time will be shortened, provided you you have multiple hardware threads available.
The problem is in how you measure time: clock returns the processor time used by the program. That means, it sums the time taken by all the threads. If your program uses 2 threads, and it's linear execution time is 1 second, that means that each thread has used 1 second of CPU time, and clock will return the equivalent of 2 seconds.
To get the actual time used (on Linux), use gettimeofday. I modified your code by adding
#include <sys/time.h>
and capturing the start time before the loop:
struct timeval tv_start;
gettimeofday( &tv_start, NULL );
and after:
struct timeval tv_end;
gettimeofday( &tv_end, NULL );
and calculating the difference in seconds:
printf("CPU Time: %lf\nTime passed: %lf\n",
time_spent,
((tv_end.tv_sec * 1000*1000.0 + tv_end.tv_usec) -
(tv_start.tv_sec * 1000*1000.0 + tv_start.tv_usec)) / 1000/1000
);
(I also fixed the malloc from malloc(sizeof(ranges)) which allocates the size of a pointer (4 or 8 bytes for 32/64 bit CPU) to malloc(sizeof(struct range)) (12 bytes)).
When running with the input parameters 0 1000000000 1000000000 1, that is, 1 billion iterations in 1 thread, the output on my machine is:
CPU Time: 4.352000
Time passed: 4.400006
When running with 0 1000000000 1000000000 2, that is, 1 billion iterations spread over 2 threads (500 million iterations each), the output is:
CPU Time: 4.976000
Time passed: 2.500003
For completeness sake, I tested it with the input 0 1000000000 1000000000 4:
CPU Time: 8.236000
Time passed: 2.180114
It is a little faster, but not twice as fast as with 2 threads, and it uses double the CPU time. This is because my CPU is a Core i3, a dual-core with hyperthreading, which aren't true hardware threads.

Ising 1-Dimensional C - program

i am trying to simulate the Ising Model 1-D. This model consists in a chain of spin (100 spins) and using the Mont Carlo - Metropolis to accept the flip of a spin if the energy of the system (unitary) goes down or if it will be less than a random number.
In the correct program, both the energy the magnetization go to zero, and we have the results as a Gaussian (graphics of Energyor the magnetization by the number of Monte Carlo steps).
I have done some work but i think my random generator isn't correctt for this, and i don't know how/where to implement the boundary conditions: the last spin of the chain is the first one.
I need help to finish it. Any help will be welcome. Thank you.
I am pasting my C program down:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h> //necessary for function time()
#define LENGTH 100 //size of the chain of spins
#define TEMP 2 // Temperature in units of J
#define WARM 200 // Termalização
#define MCS 20000 //Monte Carlo Steps
void start( int spin[])
{
/* starts with all the spins 1 */
int i;
for (i = 0 ; i < 100; i++)
{
spin[i] = 1;
}
}
double energy( int spin[]) //of the change function J=1
{
int i;
double energyX=0;// because the begining Energy = -J*sum (until 100) =-100,
for (i = 0;i<100;i++)
energyX=energyX-spin[i]*spin[i+1];
return(energyX);
}
int randnum(){
int num;
srand(time(NULL));
/* srand(time(NULL)) objectives to initiate the random number generator
with the value of the function time(NULL). This is calculated as being the
total of seconds passed since january first of 1970 until the present date.
So, this way, for each execution the value of the "seed" will be different.
*/
srand(time(NULL));
//picking one spin randomly zero to 100
num=rand() % 100;
printf("num = %d ", num);
return num;
}
void montcarlo( int spin[])
{
int i,j,num;
double prob;
double energyA, energyB; // A -> old energy and B -> the new energy
int rnum1,rnum2;
prob=exp(-(energyB-energyA)/TEMP);
energyA = 0;
energyB = 0;
for (i = 0;i<100;i++)
{
for (j = 0;j<100;j++)
{
energyA=energy(spin);
rnum1=randnum();
rnum2=randnum(); // i think they will give me different numbers
spin[rnum1] = -spin[rnum1]; //flip of the randomly selected spin
energyB = energyB-spin[j]*spin[j+1];
if ((energyB-energyA<0)||((energyB-energyA>0)&&(rnum2>prob))){ // using rnum2 not to be correlated if i used rnum1
spin[rnum1]=spin[rnum1];} // keep the flip
else if((energyB-energyA>0)&&(rnum2<prob))
spin[rnum1]=-spin[rnum1]; // unflip
}
}
}
int Mag_Moment( int spin[] ) // isso é momento magnetico
{
int i;
int mag;
for (i = 0 ; i < 100; i++)
{
mag = mag + spin[i];
}
return(mag);
}
int main()
{
// starting the spin's chain
int spin[100];//the vector goes til LENGHT=100
int i,num,j;
int itime;
double mag_moment;
start(spin);
double energy_chain=0;
energy_chain=energy(spin); // that will give me -100 in the begining
printf("energy_chain starts with %f", energy_chain);// initially it gives -100
/*Warming it makes the spins not so ordered*/
for (i = 1 ; i <= WARM; i++)
{
itime = i;
montcarlo(spin);
}
printf("Configurtion after warming %d \n", itime);
for (j = 0 ; j < LENGTH; j++)
{
printf("%d",spin[j]);
}
printf("\n");
energy_chain=energy(spin); // new energy after the warming
/*openning a file to save the values of energy and magnet moment of the chain*/
FILE *fp; // declaring the file for the energy
FILE *fp2;// declaring the file for the mag moment
fp=fopen("energy_chain.txt","w");
fp2=fopen("mag_moment.txt","w");
int pures;// net value of i
int a;
/* using Monte Carlo metropolis for the whole chain */
for (i = (WARM + 1) ; i <= MCS; i++)
{
itime=i;//saving the i step for the final printf.
pures = i-(WARM+1);
montcarlo(spin);
energy_chain = energy_chain + energy(spin);// the spin chain is moodified by void montcarlo
mag_moment = mag_moment + Mag_Moment(spin);
a=pures%10000;// here i select a value to save in a txt file for 10000 steps to produce graphs
if (a==0){
fprintf(fp,"%.12f\n",energy_chain); // %.12f just to give a great precision
fprintf(fp2,"%.12f\n",mag_moment);
}
}
fclose(fp); // closing the files
fclose(fp2);
/* Finishing -- Printing */
printf("energy_chain = %.12f\n", energy_chain);
printf("mag_moment = %.12f \n", mag_moment);
printf("Temperature = %d,\n Size of the system = 100 \n", TEMP);
printf("Warm steps = %d, Montcarlo steps = %d \n", WARM , MCS);
printf("Configuration in time %d \n", itime);
for (j = 0 ; j < 100; j++)
{
printf("%d",spin[j]);
}
printf("\n");
return 0;
}
you should call srand(time(NULL)); only once in your program. Every time you call this in the same second you will get the same sequence of random numbers. So it is very likely that both calls to randnum will give you the same number.
Just add srand(time(NULL)); at the begin of main and remove it elsewhere.
I see a number of bugs in this code, I think. The first one is the re-seeding of the srand() each loop which has already been addressed. Many of the loops go beyond the array bounds, such as:
for (ii = 0;ii<100;ii++)
{
energyX = energyX - spin[ii]*spin[ii+1];
}
This will give you spin[99]*spin[100] for the last loop, for which is out of bounds. That is kind of peppered throughout the code. Also, I noticed the probability rnum2 is an int but compared as if it's supposed to be a double. I think dividing the rnum2 by 100 will give a reasonable probability.
rnum2 = (randnum()/100.0); // i think they will give me different numbers
The initial probability used to calculate the spin is, prob=exp(-(energyB-energyA)/TEMP); but both energy values are not initialized, maybe this is intentional, but I think it would be better to just use rand(). The Mag_Moment() function never initializes the return value, so you wind up with a return value that is garbage. Can you point me to the algorithm you are trying to reproduce? I'm just curious.

C how to measure time correctly?

This is the "algorithm", but when I want to measure the execution time it gives me zero. Why?
#define ARRAY_SIZE 10000
...
clock_t start, end;
start = clock();
for( i = 0; i < ARRAY_SIZE; i++)
{
non_parallel[i] = vec[i] * vec[i];
}
end = clock();
printf( "Number of seconds: %f\n", (end-start)/(double)CLOCKS_PER_SEC );
So What should i do to measure the time?
Two things:
10000 is not a lot on a modern computer. Therefore that loop will run in probably less than a millisecond - less than the precision of clock(). Therefore it will return zero.
If you aren't using the result of non_parallel its possible that the entire loop will be optimized out by the compiler.
Most likely, you just need a more expensive loop. Try increasing ARRAY_SIZE to something much larger.
Here's a test on my machine with a larger array size:
#define ARRAY_SIZE 100000000
int main(){
clock_t start, end;
double *non_parallel = (double*)malloc(ARRAY_SIZE * sizeof(double));
double *vec = (double*)malloc(ARRAY_SIZE * sizeof(double));
start = clock();
for(int i = 0; i < ARRAY_SIZE; i++)
{
non_parallel[i] = vec[i] * vec[i];
}
end = clock();
printf( "Number of seconds: %f\n", (end-start)/(double)CLOCKS_PER_SEC );
free(non_parallel);
free(vec);
return 0;
}
Output:
Number of seconds: 0.446000
This is an unreliable way to actually time number of seconds, since the clock() function is pretty low precision, and your loop isn't doing a lot of work. You can either make your loop do more so that it runs longer, or use a better timing method.
The higher precision methods are platform specific. For Windows, see How to use QueryPerformanceCounter? and for linux see High resolution timer with C++ and Linux?

Resources