Ускорить программу на C, используя pthreads - PullRequest
0 голосов
/ 29 марта 2012

Я новичок здесь, а также я относительно новичок в программировании в целом.Я написал программу на C, и мне нужно ускорить ее, используя pthreads.Я пытался сделать это с помощью OpenMP, но я не знаю, как его отладить.Также мне нужно выяснить, быстрее ли программа использует pthreads и время, но я не знаю, как написать это в своем коде.Вот мой код

enter code here
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#define NTHREADS 2
#define FYLLO(komvos) ((komvos) * 2 + 1)

long factorial(long);
void heap_function (int [], int, int );
void make_heap(long [], int );
void pop_heap(long [], int );

struct thread_data
{
long int    n;
long int k;
long *b;
};

main()
{

  long int n,k,c,fact=1;
  long *a,*b,*d,p[k];
  int i,j,rc;
  int q[]={2,3,4,5,6,7,8,9,12,13,14,15,16};
  pthread_t thread[NTHREADS];
  struct thread_data threada;
  for(i=0;i<NTHREADS;i++)
  {
    threada.n=n;
    threada.k=k;
    threada.b=b;
    pthread_create (&thread[i], NULL, (void *)&threada);
  }
  for (i=0; i<NTHREADS; i++) 
    rc = pthread_join (thread[i], NULL);

  for(i=0;i<13;i++)
  {
    k=pow(2,q[i])-1;
    if(a=(long*)malloc(i*sizeof(long))==NULL);
    {
       printf("Den yparxei diathesimi mnimi gia desmeusi\n");
       exit(1);
    }
    a[i]=k;
    for(a[0];a[13];a[i]++)
    {
        n=(pow(2,q[i]))*k;
        if(d=(long*)malloc((i*i)*sizeof(long))==NULL);
        {
            printf("Den yparxei diathesimi mnimi gia desmeusi\n");
            exit(1);
        }
        d[i]=n;
    }  
  c=(factorial(n))/((factorial(k))*(factorial(n-k)));     
  } 
  if(b=(long*)malloc(((i*i)+i)*sizeof(long))==NULL)
    {
        printf("Den yparxei diathesimi mnimi gia desmeusi\n");
        exit(1);
    }
  for(i=0;i<13;i++)
  {
    b[i]=a[i];
  }
  for(i=13;i<182;i++)                     /* Gia i=13 exoume i^2=169 kai i^2+i=182*/
  {
    b[i]=d[i];
  }    
  long heap[sizeof(b)];
  make_heap( heap, sizeof(b) );
  printf("To heap einai:\n");        
    for ( i = sizeof(b); i >=0; i-- ) 
        {
            printf( "%d ", heap[0] );
            pop_heap( heap, i );
        }
    for(i=(n-k);i<=n;i++)
        for(j=0;j<k;j++)
        {
            p[j]=heap[i];
            printf("Ta %d mikrotera stoixeia eina ta %ld\n",k,p[j]);
        } 
  free((void*)b);             
  getch();
}



long factorial(long n)
{
   int a;
   long result=1;

   for( a=1;a<=n;a++ )
     result=result*a;

   return(result);
}



void heap_function( int a[], int i, int n )
{

  while ( FYLLO( i ) < n )                  /* Vazoume sto heap ta stoixeia san           ypodentra */
{

  int fyllo = FYLLO( i );


  if ( fyllo + 1 < n && a[fyllo] < a[fyllo + 1] )     /* Dialegoume to maegalytero apo ta dyo paidia komvous */
  ++fyllo;


  if ( a[i] < a[fyllo] )                      /* Metaferoume to megalytero komvo sti riza */
  {
    int k = a[i];
    a[i] = a[fyllo];
    a[fyllo] = k;
  }


  ++i;                                    /* Synexizoume ston epomeno komvo */
  }
}


void make_heap( long a[], int n )        /*Dhmioyrgoume ti sinartisi make_heap gia na  mporesoume na valoume ta
                                        stoixeia pou dwsame mesa sto heap kai na ta ta3inomisoume*/
{
  int i = n / 2;

  while ( i-- > 0 )
  heap_function( a, i, n );
}


void pop_heap( long heap[], int n )      /*Dhmiourgoume ti sinartisi pop_heap gia na  mporesoume na e3agoume 
                                        ta stoixeia apo to heap apo to megalytero sto mikrotero*/
{
  long k = heap[0];
  heap[0] = heap[n];
  heap[n] = k;
  heap_function( heap, 0, n );          /*Afou emfanistei to prwto stoixeio kaloume ti  sinartisi heap_function 
                                        gia na ta3inomisei ta stoixeia pou menoun sto heap*/
}

Извините за испорченную почту, но я ее новенькая, теперь я ее использую

1 Ответ

5 голосов
/ 29 марта 2012

Добавление потоков может не ускорить вашу программу, оно позволяет вам организовать вашу работу в исполнительные блоки, которые могут работать параллельно (а в многоядерных системах, как правило, могут работать параллельно). Если вы не в многоядерной системе, вы все равно можете получить преимущество, если один или несколько ваших потоков должны блокировать ожидание медленного ввода, потому что другие потоки могут продолжать работать; это может или не может дать вам более быстрое время выполнения, в зависимости от вашей фактической программы.

Отладка потоков, как правило, сложнее, чем отладка отдельного потока, и то, как это сделать, зависит от имеющихся у вас инструментов. Если ваш отладчик не в состоянии упростить вам задачу, я бы рекомендовал вам сначала запустить вашу программу поочередно - все равно разбивайте ее, используя многопоточную модель, но позвольте коду для каждого запуска в основном потоке и разрешите его запуск до завершения, если ваша модель позволяет это. Многие многопоточные приложения не могут быть написаны так, потому что потоки зависят друг от друга во время выполнения, но это просто зависит от того, что вы делаете точно.

Теперь к вашей конкретной ситуации - вы погружаетесь в глубокий конец, когда еще не знаете, как плавать. Я бы посоветовал вам сначала научиться использовать потоки без какой-либо сложности, зачем они вам нужны, иначе вы усложняете проблему, чем она должна быть. http://cs.gmu.edu/~white/CS571/Examples/Pthread/create.c имеет простой пример для начала. Обратите особое внимание на параметры вызова pthread_create() и сравните с тем, что вы сделали; в вашем коде отсутствует третий параметр - функция, запускаемая как поток. Похоже, у вас вообще нет такой функции, и вместо этого вы, похоже, полагаете, что код, следующий за вызовом pthread_create(), работает параллельно. Вот как работает fork(), но это совсем другое дело.

Этого должно быть достаточно, чтобы начать. http://cs.gmu.edu/~white/CS571/Examples/pthread_examples.html содержит дополнительные примеры, и Google "pthread tutorial", вероятно, будет полезен.

...