81 lines
2.0 KiB
C
81 lines
2.0 KiB
C
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <pthread.h>
|
||
|
|
#include <sys/time.h>
|
||
|
|
|
||
|
|
#define MAX_THREADS 64
|
||
|
|
#define N 1000000000LL
|
||
|
|
|
||
|
|
long long global_sum = 0;
|
||
|
|
long long nelems_per_thread;
|
||
|
|
pthread_mutex_t mutex;
|
||
|
|
|
||
|
|
void *sum_squares_thread(void *arg)
|
||
|
|
{
|
||
|
|
long long start = *(long long *)arg;
|
||
|
|
long long end = start + nelems_per_thread;
|
||
|
|
if (end > N) end = N;
|
||
|
|
long long local_sum = 0;
|
||
|
|
for (long long i = start; i < end; i++) {
|
||
|
|
local_sum += i * i;
|
||
|
|
}
|
||
|
|
pthread_mutex_lock(&mutex);
|
||
|
|
global_sum += local_sum;
|
||
|
|
pthread_mutex_unlock(&mutex);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
double get_time()
|
||
|
|
{
|
||
|
|
struct timeval tv;
|
||
|
|
gettimeofday(&tv, NULL);
|
||
|
|
return tv.tv_sec + tv.tv_usec / 1000000.0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(int argc, char *argv[])
|
||
|
|
{
|
||
|
|
if (argc != 2) {
|
||
|
|
fprintf(stderr, "Usage: %s <num_threads>\n", argv[0]);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
int nthreads = atoi(argv[1]);
|
||
|
|
if (nthreads > MAX_THREADS) nthreads = MAX_THREADS;
|
||
|
|
|
||
|
|
nelems_per_thread = N / nthreads;
|
||
|
|
pthread_mutex_init(&mutex, NULL);
|
||
|
|
|
||
|
|
pthread_t threads[MAX_THREADS];
|
||
|
|
long long starts[MAX_THREADS];
|
||
|
|
|
||
|
|
global_sum = 0;
|
||
|
|
double t_start = get_time();
|
||
|
|
|
||
|
|
for (int i = 0; i < nthreads; i++) {
|
||
|
|
starts[i] = i * nelems_per_thread;
|
||
|
|
pthread_create(&threads[i], NULL, sum_squares_thread, &starts[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 0; i < nthreads; i++) {
|
||
|
|
pthread_join(threads[i], NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
double t_end = get_time();
|
||
|
|
double elapsed = t_end - t_start;
|
||
|
|
|
||
|
|
__int128 n = N;
|
||
|
|
__int128 expected = (n - 1) * n * (2 * n - 1) / 6;
|
||
|
|
printf("Threads: %d, Sum of squares: %lld, Expected: (see below), Time: %.6f s\n",
|
||
|
|
nthreads, global_sum, elapsed);
|
||
|
|
/* expected ≈ 3.33e26, too large for long long; print high/low 64-bit parts */
|
||
|
|
unsigned long long lo = (unsigned long long)expected;
|
||
|
|
unsigned long long hi = (unsigned long long)(expected >> 64);
|
||
|
|
if (hi)
|
||
|
|
printf("Expected (hex): %llx%016llx\n", hi, lo);
|
||
|
|
else
|
||
|
|
printf("Expected: %llu\n", lo);
|
||
|
|
|
||
|
|
pthread_mutex_destroy(&mutex);
|
||
|
|
return 0;
|
||
|
|
}
|