2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Параллельная программа (threads) / С
Сообщение16.03.2014, 08:05 


15/03/14
1
Мне нужно распараллелить программу: решения слау методом вращений.
Вот, что я написала:
Код:
typedef struct DATA
{
    double *a;
    double *b;
    int n;
    int num_thr;
    int total_thr;
}  DATA;

void * rotation_threaded(void *pa)
{
    long int thread_time;
    DATA *data=(DATA*)pa ;
    thread_time=get_time();
    solve(data->a,data->n,data->b,data->num_thr,data->total_thr);
    thread_time=get_time()-thread_time;
    pthread_mutex_lock(&mutex);
    printf("\nThread time: %ld\n", thread_time/(data->total_thr));
    pthread_mutex_unlock(&mutex);
    return 0;

}


основная функция, потоки параллельно работают со столбцами(num_thr-номер текущего, total_thr - всего потоков ):
Код:
void solve (double *a, int n, double *b, int num_thr,int total_thr)
{
    int i,j,last,k;
    double n1=0,m=0,cos=0,sin=0;
    double h;
    last=n-1-num_thr;
    long int t_full0,sum0=0;
    long int t_full1, sum1=0;
    for(i=0;i<n;i++){
        for(j=i+1;j<n;j++){
            cos=0;sin=0;n1=0;m=0;
            if (num_thr==0)
            t_full0=get_full_time();
            if (num_thr==1)
            t_full1=get_full_time();
///////////////////////////////////////////////////////////////////////////////
            synchronize (total_thr);
            n1=a[j*n+i];
            m=a[i*n+i];
            cos=m/sqrt(m*m+n1*n1);
            sin=n1/sqrt(m*m+n1*n1);
            synchronize (total_thr);
///////////////////////////////////////////////////////////////////////////////
            t_full=get_full_time()-t_full;
            for (k=last;k>=i;k=k-total_thr){
                m=a[i*n+k];
                a[i*n+k]=cos*a[i*n+k]+sin*a[j*n+k];
                a[j*n+k]=-sin*m+cos*a[j*n+k];
            }           
            if (num_thr==0){
                h=b[i];
                b[i]=cos*b[i]+sin*b[j];
                b[j]=-sin*h+cos*b[j];
            }
           
            if (num_thr==0)
            t_full0=get_full_time()-t_full0;
            if (num_thr==1)
            t_full1=get_full_time()-t_full1;
            sum0+=t_full0;
            sum1+=t_full1;
        }
    }
   
    if (num_thr==0)
    printf("\nTime 0 thr  = %ld\n",sum0);
    if (num_thr==1)
    printf("\nTime 1 thr  = %ld\n",sum1);
}

функция дожидается всех потоков
Код:
void synchronize(int total_threads) {
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t condvar_in = PTHREAD_COND_INITIALIZER;
    static pthread_cond_t condvar_out = PTHREAD_COND_INITIALIZER;
    static int threads_in = 0;
    static int threads_out = 0;
    pthread_mutex_lock(&mutex);
    threads_in++;
    if (threads_in >= total_threads) {
        threads_out = 0;
        pthread_cond_broadcast(&condvar_in);
    } else
        while (threads_in < total_threads)
        pthread_cond_wait(&condvar_in,&mutex);
        threads_out++;
    if (threads_out >= total_threads) {
        threads_in = 0;
        pthread_cond_broadcast(&condvar_out);
    }
    else
        while (threads_out < total_threads)
            pthread_cond_wait(&condvar_out,&mutex);
        pthread_mutex_unlock(&mutex);
}

ну и соответственно main
Код:
int main(int argc, char * argv[]) {
    .........................
    for(i=0;i<total_thr;i++)
    {
    data[i].a=a;
    data[i].b=b;
    data[i].n=n;
    data[i].num_thr=i;
    data[i].total_thr=total_thr;
    }
    t_full=get_full_time();     
    for(i=0;i<total_thr;i++) {
        if (pthread_create(threads+i,0,rotation_threaded,data+i)) {
            printf("Cannot create thread %d!\n", i);
            if (a) free(a);
            if (b) free(b);
            if (threads) free(threads);
            if (data) free(data);
            return -2;
        }
       
    }
    for(i=0;i<total_thr;i++) {
        if (pthread_join(threads[i], 0)) {
            printf("Cannot wait thread %d!\n",i);
            if (a) free(a);
            if (b) free(b);
            if (threads) free(threads);
            if (data) free(data);
            return -3;
        }
    }
    t_full=get_full_time()-t_full;
    printf("\nTime  = %ld\n",t_full);
    ...............................
    return 0;
}

Из-за того, что в функции solve 2(n-1)! раз вызывается synchronize программа с увеличением числа потоков работает только медленнее. Если synchronize убираю, то скорость такая, какая должна быть. Но считает не правильно. Если выносить подсчет cos,sin за пределы создания потоков, тогда pthread_create будет вызываться (n-1)! раз, что естественно тоже только замедляет программу.
Как распараллелить, кроме как по столбцам не знаю. По строкам не получиться, так как одновременно меняю и i и j строку.
Подскажите, пожалуйста, как поменять алгоритм или исправить мой код.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group