3by3线程同步:如何避免开销

时间:2012-12-01 03:15:37

标签: c multithreading parallel-processing synchronization pthreads

假设我正在运行N个线程。 每个线程都需要与下一个和前一个线程同步。

    for (i = 0 ; i < NITER; i++){
      do_something ();
      sync_with_neighbours (tId - 1, tId + 1);
    }

我需要以最有效的方式实现同​​步。 Pthread障碍效率不高,因为这样每个线程都会等待最慢的线程到达屏障。

欢迎任何想法

编辑:

不,我们不必等待线程0:

如果这两个相邻线程“i + 1”和“i - 1”准备好,则线程“i”将运行。

假设在时间T我们正在运行6个线程:

  • th0:pending(运行iter = m)
  • th1:pending(运行iter = m)
  • th2:ready(等待)
  • th3:准备好(等待)
  • th4:ready(等待)
  • th5:pending(运行iter = m)

T + 1的情况将是:

  • th0:pending(运行iter = m)
  • th1:pending(运行iter = m)
  • th2:ready(等待)
  • th3:运行iter = m + 1
  • th4:ready(等待)
  • th5:pending(运行iter = m)

所以你可以看到每个人都不需要等待Th0

2 个答案:

答案 0 :(得分:3)

我假设(按照你的例子)你的意思是同步化没有真正的rendenzvous,而是交叉信号。因此,如果每个邻居获得一个空闲信号,任何线程都可以运行。 为此,您可以使用信号量,每个线程一个。 同步部分如下所示:

   UP(left_sem)
   UP(right_sem)
   DOWN(own_sem,2)

(第一个和最后一个帖子没有左或右邻居,因此,他们只需要一个简单的DOWN

关于实现:经典的System V信号似乎是合适的,因为System V系统已经调用已经有信号量数组的交易,因此你只需要做一些索引。 但是,每种信号量都应该足够了。

答案 1 :(得分:1)

只是为了好玩 - 你可以查看我的生命游戏编码示例 -

http://parallel.cc/cgi-bin/bfx.cgi/test_cases.html

但由于你没有ParC,并且坚持使用pThreads,这有点棘手。最快的同步方法通常是使用一种简单的信号量机制,其中(p)线程保持热,只读取一个内存位置,直到它发生变化(例如等待它为非零)。

要记住的事情:

如果你将数据和信号量分开,使得通过内存子系统的写入不是原子的和/或有序的,那么东西可能无法工作(有时),所以至少确保一切都在同一个缓存行上,如果可能的话,否则校验和您的数据,以便接收方知道它有一套完整的数据。

注意1:我假设你的意思是“速度”而不是“效率”,并且你拥有与线程一样多的内核。

注2:pThreads来自OS级别的多线程(粗略),只是在这个级别上很糟糕(很好)。