2017-01-01 9 views
3

В настоящее время я имею многопоточную C-программу, закодированную с использованием Pthreads, которая использует 2 потока. Я хочу увеличить нет. нитей и меры ускоряются при этом. Я хотел бы запустить мой код в автоматическом режиме, где нет. используемых потоков продолжает увеличиваться, и я хочу графически отображать время работы моего кода. Мне бы это понравилось, если бы я мог понять, как это сделать, особенно о том, как автоматизировать весь процесс и графически его графически отображать. Вот мой код:Измерение скорости многопоточной программы C (реализация с использованием Pthreads)

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#define NUM_THREADS 2 
#define VECTOR_SIZE 40 

struct DOTdata 
{ 
    /* data */ 
    long X[VECTOR_SIZE]; 
    long Y[VECTOR_SIZE]; 
    long sum; 
    long compute_length; 
}; 

struct DOTdata dotstr; 
pthread_mutex_t mutex_sum; 

void *calcDOT(void *); 

int main(int argc, char *argv[]) 
{ 
    long vec_index; 

    for(vec_index = 0 ; vec_index < VECTOR_SIZE ; vec_index++){ 
     dotstr.X[vec_index] = vec_index + 1; 
     dotstr.Y[vec_index] = vec_index + 2; 
    } 

    dotstr.sum = 0; 
    dotstr.compute_length = VECTOR_SIZE/NUM_THREADS; 

    pthread_t call_thread[NUM_THREADS]; 
    pthread_attr_t attr; 
    void *status; 

    pthread_mutex_init(&mutex_sum, NULL); 

    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

    long i; 

    for(i = 0 ; i < NUM_THREADS ; i++){ 
     pthread_create(&call_thread[i], &attr, calcDOT, (void *)i); 
    } 

    pthread_attr_destroy(&attr); 

    for (i = 0 ; i < NUM_THREADS ; i++){ 
     pthread_join(call_thread[i], &status); 
    } 

    printf("Resultant X*Y is %ld\n", dotstr.sum); 
    pthread_mutex_destroy(&mutex_sum); 
    pthread_exit(NULL); 
} 

void *calcDOT(void *thread_id) 
{ 
    long vec_index; 
    long start_index; 
    long end_index; 
    long length; 
    long offset; 
    long sum = 0; 

    offset = (long)thread_id; 
    length = dotstr.compute_length; 

    start_index = offset * length; 
    end_index = (start_index + length) - 1; 

    for(vec_index = start_index ; vec_index < end_index ; vec_index++){ 
     sum += (dotstr.X[vec_index] * dotstr.Y[vec_index]); 
    } 

    pthread_mutex_lock(&mutex_sum); 
    dotstr.sum += sum; 
    pthread_mutex_unlock(&mutex_sum); 

    pthread_exit((void *)thread_id); 

} 

Я хотел бы, чтобы увеличить свой параметр NUM_THREADS и запустить его после каждого шага, записать время выполнения после каждого шага и построить график времени выполнения против числа потоков.

+0

Какая операционная система? И чтобы было ясно, вам уже удалось заставить ваше приложение работать с произвольным количеством потоков, или вы также ищете помощь для этого? – giusti

+0

Я написал свой код, который использует n потоков, хотя константа в течение всего цикла выполнения. Моя ОС - macOS Sierra. –

+0

Я могу изменить свой параметр NUM_THREADS и запустить его отдельно, но я хочу автоматизировать процесс, записать время выполнения каждого цикла и графически отобразить его. –

ответ

2

Я пробовал наивный подход, увеличивая количество потоков, определяя его с помощью time.h и рисуя его с помощью gnuplot. Каждая итерация удваивает количество потоков, и мы печатаем время для итерации. Мы используем GNUPLOT, чтобы отобразить граф с числом нитей на х-оси и выполнения времени на оси у

enter image description here

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

#define NUM_THREADS 2 
#define VECTOR_SIZE 40 

struct DOTdata { 
    /* data */ 
    long X[VECTOR_SIZE]; 
    long Y[VECTOR_SIZE]; 
    long sum; 
    long compute_length; 
}; 

struct DOTdata dotstr; 
pthread_mutex_t mutex_sum; 

void *calcDOT(void *); 

int main(int argc, char *argv[]) { 
    double xvals[VECTOR_SIZE/NUM_THREADS]; 
    double yvals[VECTOR_SIZE/NUM_THREADS]; 
    int index = 0; 
    for (int count = NUM_THREADS; count < VECTOR_SIZE/NUM_THREADS; count = count * 2) { 

     clock_t begin = clock(); 

     long vec_index; 

     for (vec_index = 0; vec_index < VECTOR_SIZE; vec_index++) { 
      dotstr.X[vec_index] = vec_index + 1; 
      dotstr.Y[vec_index] = vec_index + 2; 
     } 

     dotstr.sum = 0; 
     dotstr.compute_length = VECTOR_SIZE/count; 

     pthread_t call_thread[count]; 
     pthread_attr_t attr; 
     void *status; 

     pthread_mutex_init(&mutex_sum, NULL); 

     pthread_attr_init(&attr); 
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

     long i; 

     for (i = 0; i < count; i++) { 
      pthread_create(&call_thread[i], &attr, calcDOT, (void *) i); 
     } 

     pthread_attr_destroy(&attr); 

     for (i = 0; i < count; i++) { 
      pthread_join(call_thread[i], &status); 
     } 

     printf("Resultant X*Y is %ld\n", dotstr.sum); 
     pthread_mutex_destroy(&mutex_sum); 
     clock_t end = clock(); 
     double time_spent = (double) (end - begin)/CLOCKS_PER_SEC; 

     printf("time spent: %f NUM_THREADS: %d\n", time_spent, count); 
     xvals[index] = count; 
     yvals[index] = time_spent; 
     index++; 
    } 

    FILE * gnuplotPipe = popen ("gnuplot -persistent", "w"); 

    fprintf(gnuplotPipe, "plot '-' \n"); 

    for (int i = 0; i < VECTOR_SIZE/NUM_THREADS; i++) 
    { 
     fprintf(gnuplotPipe, "%lf %lf\n", xvals[i], yvals[i]); 
    } 

    fprintf(gnuplotPipe, "e"); 


    pthread_exit(NULL); 
} 

void *calcDOT(void *thread_id) { 
    long vec_index; 
    long start_index; 
    long end_index; 
    long length; 
    long offset; 
    long sum = 0; 

    offset = (long) thread_id; 
    length = dotstr.compute_length; 

    start_index = offset * length; 
    end_index = (start_index + length) - 1; 

    for (vec_index = start_index; vec_index < end_index; vec_index++) { 
     sum += (dotstr.X[vec_index] * dotstr.Y[vec_index]); 
    } 

    pthread_mutex_lock(&mutex_sum); 
    dotstr.sum += sum; 
    pthread_mutex_unlock(&mutex_sum); 

    pthread_exit((void *) thread_id); 

} 

Выходной

Resultant X*Y is 20900 
time spent: 0.000155 NUM_THREADS: 2 
Resultant X*Y is 19860 
time spent: 0.000406 NUM_THREADS: 4 
Resultant X*Y is 17680 
time spent: 0.000112 NUM_THREADS: 8 
Resultant X*Y is 5712 
time spent: 0.000587 NUM_THREADS: 16