某些并行计算需要面临某些在计算进行前的某些单通瓶颈点,这种情况下,当然可以使用信号量的方式来进行处理,但是还存在着另外的一种处理方式是更加方便的,它就是:栅栏(在pthread库里面被定义成为类型 pthread_barrier_t),下面我们来看一段程序作为示例
代码
1 #define _XOPEN_SOURCE 600 2 3 #include <pthread.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 7 8 #define ROWS 10000 9 #define COLS 1000010 #define THREADS 1011 12 double initial_matrix[ROWS][COLS];13 double final_matrix[ROWS][COLS];14 // Barrier variable15 pthread_barrier_t barr;16 17 extern void DotProduct(int row, int col,18 double source[ROWS][COLS],19 double destination[ROWS][COLS]);20 extern double determinant(double matrix[ROWS][COLS]);21 22 void * entry_point(void *arg)23 {24 int rank = (int)arg;25 for(int row = rank * ROWS / THREADS; row < (rank + 1) * THREADS; ++row)26 for(int col = 0; col < COLS; ++col)27 DotProduct(row, col, initial_matrix, final_matrix);28 29 // Synchronization point30 int rc = pthread_barrier_wait(&barr);31 if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)32 {33 printf("Could not wait on barrier\n");34 exit(-1);35 }36 37 for(int row = rank * ROWS / THREADS; row < (rank + 1) * THREADS; ++row)38 for(int col = 0; col < COLS; ++col)39 DotProduct(row, col, final_matrix, initial_matrix);40 }41 42 int main(int argc, char **argv)43 {44 pthread_t thr[THREADS];45 46 // Barrier initialization47 if(pthread_barrier_init(&barr, NULL, THREADS))48 {49 printf("Could not create a barrier\n");50 return -1;51 }52 53 for(int i = 0; i < THREADS; ++i)54 {55 if(pthread_create(&thr[i], NULL, &entry_point, (void*)i))56 {57 printf("Could not create thread %d\n", i);58 return -1;59 }60 }61 62 for(int i = 0; i < THREADS; ++i)63 {64 if(pthread_join(thr[i], NULL))65 {66 printf("Could not join thread %d\n", i);67 return -1;68 }69 }70 71 double det = Determinant(initial_matrix);72 printf("The determinant of M^4 = %f\n", det);73 74 return 0;75 }
这段程序产生出许多个线程,并且分配给每个线程计算矩阵乘法的一部分,然后每个线程使用这次计算的结果,继续进行下一步的计算:另一个矩阵的乘法
几点关于API的说明:
barrier 变量必须在最开始声名为全局变量
barrier 变量的初始化必须在main函数里进行初始化
在点上每一个线程都会等待它的对端完成工作
注意
在程序顶部的宏定义 _XOPEN_SOURCE 是非常重要的;如果没有这个变量,那么barrier类型就会在pthread.h中被屏蔽掉,这个定义必须在所有的头文件引用之前被定义出来
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/asiainfolf/archive/2010/10/02/5***801.aspx
代码
1 #define _XOPEN_SOURCE 600 2 3 #include <pthread.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 7 8 #define ROWS 10000 9 #define COLS 1000010 #define THREADS 1011 12 double initial_matrix[ROWS][COLS];13 double final_matrix[ROWS][COLS];14 // Barrier variable15 pthread_barrier_t barr;16 17 extern void DotProduct(int row, int col,18 double source[ROWS][COLS],19 double destination[ROWS][COLS]);20 extern double determinant(double matrix[ROWS][COLS]);21 22 void * entry_point(void *arg)23 {24 int rank = (int)arg;25 for(int row = rank * ROWS / THREADS; row < (rank + 1) * THREADS; ++row)26 for(int col = 0; col < COLS; ++col)27 DotProduct(row, col, initial_matrix, final_matrix);28 29 // Synchronization point30 int rc = pthread_barrier_wait(&barr);31 if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)32 {33 printf("Could not wait on barrier\n");34 exit(-1);35 }36 37 for(int row = rank * ROWS / THREADS; row < (rank + 1) * THREADS; ++row)38 for(int col = 0; col < COLS; ++col)39 DotProduct(row, col, final_matrix, initial_matrix);40 }41 42 int main(int argc, char **argv)43 {44 pthread_t thr[THREADS];45 46 // Barrier initialization47 if(pthread_barrier_init(&barr, NULL, THREADS))48 {49 printf("Could not create a barrier\n");50 return -1;51 }52 53 for(int i = 0; i < THREADS; ++i)54 {55 if(pthread_create(&thr[i], NULL, &entry_point, (void*)i))56 {57 printf("Could not create thread %d\n", i);58 return -1;59 }60 }61 62 for(int i = 0; i < THREADS; ++i)63 {64 if(pthread_join(thr[i], NULL))65 {66 printf("Could not join thread %d\n", i);67 return -1;68 }69 }70 71 double det = Determinant(initial_matrix);72 printf("The determinant of M^4 = %f\n", det);73 74 return 0;75 }
这段程序产生出许多个线程,并且分配给每个线程计算矩阵乘法的一部分,然后每个线程使用这次计算的结果,继续进行下一步的计算:另一个矩阵的乘法
几点关于API的说明:
barrier 变量必须在最开始声名为全局变量
barrier 变量的初始化必须在main函数里进行初始化
在点上每一个线程都会等待它的对端完成工作
注意
在程序顶部的宏定义 _XOPEN_SOURCE 是非常重要的;如果没有这个变量,那么barrier类型就会在pthread.h中被屏蔽掉,这个定义必须在所有的头文件引用之前被定义出来
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/asiainfolf/archive/2010/10/02/5***801.aspx