#include #include #include #include #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 \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; }