Another Approach
To run the program, you can supply two command line options. The first is the number of threads to create and the second is the number of iterations (times 1,000,000), e.g.:Will create 8 threads, giving each thread 500,000,000 iterations (4 billion in total). The results and timings are shown at the bottom of this page. You should run this program on any computers that you have access to. The more cores you have, the more interesting the results, I'd imagine../pi-atan 8 4000
pi-atan.c:
/* pi-atan.c uses long long, so no -ansi, compile with -O2 */
/* gcc -Wall -Wextra -pedantic -O2 pi-atan.c -pthread -lm -o pi-atan */
#include <stdio.h> /* printf */
#include <stdlib.h> /* exit, atoi */
#include <pthread.h> /* thread create/join/exit */
#include <unistd.h> /* getpid */
#include <math.h> /* sqrt */
/* Thread data */
struct pi_data
{
long long start; /* Starting value for thread */
long long end; /* Ending value for thread */
long long total; /* Total number of iterations */
double result; /* The approximation of pi */
double (*threadFn)(long long, long long, long long); /* PI function */
};
double atan_pi2(long long start, long long end, long long total)
{
double width = 1.0 / total;
double midpoint = (start * width) + width / 2;
double area = 0.0;
long long i;
for (i = start; i < end; i++)
{
double area_of_rectangle;
midpoint = (i * width) + width / 2;
double length = 4.0 / (1 + midpoint * midpoint);
area_of_rectangle = length * width;
area += area_of_rectangle;
/*midpoint += width;*/
}
return area;
}
void *threadFn(void *p)
{
struct pi_data *data = (struct pi_data *)p;
#ifdef DEBUG
printf("pid: %i, tid: %u\n", getpid(), (unsigned)pthread_self());
printf("start: %lli, end: %lli, total: %lli\n", data->start, data->end, data->total);
/*sleep(3);*/
#endif
/* Each thread will send the result back through the structure */
data->result = data->threadFn(data->start, data->end, data->total);
return NULL;
}
int main(int argc, char **argv)
{
int i;
int count = 1; /* Number of threads, default is 1 */
long long start = 0; /* Range start */
long long range; /* Range end */
double result = 0; /* Result of calculation (PI) */
pthread_t *threads; /* The array of threads */
struct pi_data *data; /* The array of params to threadFn */
long long iterations; /* Number of total iterations */
/* Default number of iterations */
iterations = 1000LL * 1000LL * 100LL;
/* If user provided the number of threads to run */
if (argc > 1)
count = atoi(argv[1]);
/* If the user provided the number of iterations */
if (argc > 2)
iterations = 1000LL * 1000LL * atoi(argv[2]);
/* The size (range) of each thread's data */
range = iterations / count;
/* Threads and data structures for Pthread API */
threads = malloc(count * sizeof(pthread_t));
data = malloc(count * sizeof(struct pi_data));
/* For each thread */
for (i = 0; i < count; i++)
{
int result;
data[i].start = start;
data[i].end = start + range;
data[i].total = iterations;
data[i].threadFn = atan_pi2;
result = pthread_create(&threads[i], NULL, threadFn, &data[i]);
if (result == -1)
{
printf("Thread #%i failed. ", i);
perror("pthread_create");
}
start += range;
}
/* Wait on the threads, order is unimportant */
for (i = 0; i < count; i++)
{
pthread_join(threads[i], NULL);
result += data[i].result;
}
/* Show results */
printf(" Threads: %2i\n", count);
printf("Iterations: %10lli\n", iterations);
printf(" atan: %14.12f\n", result);
/* Clean up */
free(threads);
free(data);
return 0;
}
Output: (Using Maya)
| 1 Thread | 2 Threads | |
|---|---|---|
|
|
| 4 Threads | 8 Threads | |
|---|---|---|
|
|
| 1 Thread | 2 Threads | 3 Threads | 4 Threads | |||
|---|---|---|---|---|---|---|
|
|
|
|
| 5 Threads | 6 Threads | 7 Threads | 8 Threads | |||
|---|---|---|---|---|---|---|
|
|
|
|
| 9 Threads | 10 Threads | 11 Threads | 12 Threads | |||
|---|---|---|---|---|---|---|
|
|
|
|