2

我正在编写一个基本代码来添加两个矩阵并记下单线程和 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程序记录运行时间。

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

我认为这是因为所有线程都在同一个矩阵地址区域上工作,可能是因为瓶颈没有产生任何加速。尽管所有线程都将在矩阵的不同段上工作,但它们不会重叠。

以前我实现了一个并行合并排序和一个快速排序,它们也显示出类似的特征,当我将特定线程要工作的数据段复制到新分配的内存时,我能够获得加速。

我的问题是这是因为:

  1. 内存瓶颈?
  2. 时间基准没有以正确的方式完成?
  3. 数据集太小?
  4. 编码错误?
  5. 其他

在这种情况下,如果是内存瓶颈,那么每个并行程序是否都使用独占内存区域,即使共享内存上的线程的多次访问也可以在没有互斥锁的情况下完成?

编辑

当我制作矩阵段时,我可以看到加速

  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 的小尺寸矩阵时。在每次迭代中调用并行添加之前,我正在重新分配随机值。这里注意到的加速是真的吗?还是由于其他一些现象的chaching 效应?

4

1 回答 1

2

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

为了了解正确的实现对并发程序的运行时间有多大影响,以下是程序将两个矩阵相乘的结果:

seconds  name    
10.72   simpleMul
5.16   mulThread
3.19   tilingMulThread
于 2012-09-02T05:51:53.180 回答