pthread加速矩阵加/乘

时间:2012-09-02 04:25:02

标签: c pthreads

我正在编写一个基本代码来添加两个矩阵,并记下单线程和2个或更多线程所用的时间。在该方法中,首先在THREADS段数中划分给定的两个矩阵(随机初始化),然后将这些段中的每一个发送到加法模块,该模块由pthread_create调用启动。并行加法函数的参数如下。

struct thread_segment
{
  matrix_t *matrix1, *matrix2, *matrix3;
  int start_row, offset;
};

指向两个源矩阵和一个目标矩阵的指针。 (一旦源和目的地可能指向相同的矩阵)。 start_row是特定线程应该开始添加的行,offset告诉这个线程应该从start_row开始添加多少。

matrix_t是一个简单的结构,定义如下:

typedef struct _matrix_t
{
  TYPE **mat;
  int r, c;
} matrix_t;

我用2个线程编译它,但是当我用10000 x 10000矩阵运行时(几乎)没有加速。我正在使用time -p程序记录运行时间。

矩阵随机初始化也像上面那样并行完成。

我认为这是因为所有线程都在同一个矩阵地址区域工作,可能是因为瓶颈并没有加速。虽然所有线程都可以在矩阵的不同段上工作,但它们不会重叠。

之前我实现了并行mergesort和quicksort,它也显示了类似的特性,当我将特定线程要处理的数据段复制到新分配的内存时,我能够获得加速。

我的问题是这是因为:

  1. 内存瓶颈?
  2. 时间基准没有以正确的方式完成?
  3. 数据集太小了?
  4. 编码错误?
  5. 其他
  6. 在这种情况下,如果它是一个内存瓶颈,那么每个并行程序是否都使用独占内存区域,即使在没有互斥锁的情况下可以多次访问共享内存上的线程?

    修改

    当我制作像

    这样的矩阵段时,我可以看到加速
      curr = 0;
      jump = matrix1->r / THREADS;
    
      for (i=0; i<THREADS; i++)
      {
        th_seg[i].matrix1 = malloc (sizeof (matrix_t));
        th_seg[i].matrix1->mat = &(matrix1->mat[curr]);
        th_seg[i].matrix1->c = matrix1->c;
        th_seg[i].matrix1->r = jump;
    
        curr += jump;
      }
    

    即在传递之前,在结构中分配要由此线程处理的矩阵的基地址并存储行数。所以现在每个矩阵的基地址对于每个线程都是不同的。但只有当我添加一些小尺寸矩阵100 x 100说,多次。在每次迭代中调用并行添加之前,我正在重新分配随机值。加速注意到这里是真的吗?还是由于其他一些现象的影响?

1 个答案:

答案 0 :(得分:2)

要优化内存使用情况,您可能需要查看loop tiling。这将有助于缓存内存更新。在这种方法中,您可以将矩阵划分为更小的块,以便缓存可以保存更长时间的值,而不需要经常更新它。
另请注意,创建多个线程只会增加在它们之间切换的开销。

为了感觉正确的实现可以影响并发程序的运行时间,这些是在天真,cocnurrent和tiling-concurrent中将两个矩阵相乘的程序的结果:

seconds  name    
10.72   simpleMul
5.16   mulThread
3.19   tilingMulThread