MPI中的Pthreads

时间:2012-09-10 12:37:19

标签: pthreads mpi

嗨,我写了一个MPI快速排序程序,其工作原理如下:

在我的群集中,“Master”将划分整数数据并将其发送到“Slave nodes”。在从属节点接收时,每个从属设备将执行单独的排序操作并将已排序的数据发送回主设备。 现在我的问题是我有兴趣为奴隶引入超线程。

我有来自主人的数据

  1. sub(表示数组)
  2. count(数组的大小)
  3. 现在我已将Pthreads初始化为

     num_threads=12.
        pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
      for (i = 0; i < num_pthreads; i++) {
        if (pthread_create(&thread[i], &attr, new_thread, (void *) &sub[i])) 
        {
           printf("error creating a new thread \n");
           exit(1);
        }
        else
        {
            printf(" threading is successful %d  at node %d \n \t ",i,rank);
        }       
    

    并在新的线程函数中

    void * new_thread(int *sub)
    {
    
        quick_sort(sub,0, count-1);
        }
        return(0);
    }
    

    我不明白我的方式是否正确。任何人都可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

你的基本想法是正确的,除了你还需要确定如何从线程中获得结果。

通常,您希望传递线程的所有相关信息,以通过*arg中的pthread_create参数完成其任务。在new_thread()函数中,count变量未传递给函数,因此在所有线程之间是全局的。更好的方法是通过pthread_create传递指向结构的指针。

typedef struct {
    int *sub; /* Pointer to first element in array to sort, different for each thread. */
    int count; /* Number of elements in sub. */
    int done; /* Flag to indicate that sort is complete. */
} thread_params_t


void * new_thread(thread_params_t *params)
{
   quick_sort(params->sub, 0, params->count-1); 
   params->done = 1;
   return 0;
}

您将为每个生成的线程填写一个新的thread_params_t

必须管理的另一个项目是排序结果。主线程在每个线程上执行pthread_join并确保在继续之前已完成它是正常的。根据您的要求,您可以让每个线程直接将结果发送回主服务器,主要功能是从每个线程收集结果并将结果发送回工作线程外部。

答案 1 :(得分:0)

您可以使用OpenMP而不是pthreads(仅用于记录 - 将MPI与线程组合称为混合编程)。它是一组轻量级的编译器编译指示,可将顺序代码转换为并行代码。几乎所有现代编译器都支持OpenMP。使用OpenMP,您可以引入所谓的并行区域。在并行区域的开头创建一组线程,然后代码继续并发执行,直到并行区域结束,其中所有线程都连接在一起,并且只有主线程继续执行(线程创建和连接是逻辑的,例如,它不必在现实生活中像这样实现,并且大多数实现实际上使用线程池来加速线程的创建):

#pragma omp parallel
{
   // This code gets executed in parallel
   ...
}

您可以在并行块中使用omp_get_thread_num()来获取线程的ID并使其计算不同的内容。或者您可以使用OpenMP的一个工作共享结构,如forsections等,以使其自动划分工作。

OpenMP的最大优点是不会对源代码进行深度更改,并且它会抽象创建/加入线程,因此您无需手动执行此操作。大部分时间你都可以通过几个pragma来解决问题。然后,您必须在编译期间启用OpenMP(GCC为-fopenmp,英特尔编译器为-openmp,Sun / Oracle编译器为-xopenmp,等等。如果您没有启用OpenMP或特定编译器不支持它,您将获得一个串行程序。

您可以在LLNL找到快速而全面的OpenMP教程。