【问题标题】:How do I handle n different OpenMP critical sections?如何处理 n 个不同的 OpenMP 关键部分?
【发布时间】:2017-09-23 10:01:11
【问题描述】:

假设我有n 队列。我也有n 线程。每个线程都可以加入任何n 队列。如何确保每个队列在任何时候都被最多 1 个线程访问?

如果只是 1 个队列,我会将入队操作放在 critical 部分中。但是,我不能在这里这样做,因为将所有入队操作放在 critical 部分中意味着线程 4 将无法写入队列 6,因为线程 7 正在写入队列 9。这将导致性能下降。

我想知道我是否可以并行化所有入队操作,以便每个队列本身最多由 1 个线程写入。 (本质上,锁定每个队列索引;但我想在 OpenMP 中惯用地执行此操作。)

【问题讨论】:

  • '这将导致性能不佳' - 仅当经常存在争用时。如果您只是将指针推送到队列中,那么在这么短的时间内发生锁争用的可能性有多大?
  • @MartinJames 当然,只有在存在争用时。你是对的,只推一个指针(在我的情况下是一个 int )应该不会花太多时间;但是所有队列上的全局锁定仍然可能会减慢速度。基于索引的锁至少和全队列锁一样快,对吗?
  • 也许.. 如果您不需要锁定索引。也许你可以做一个简单的布尔“inUse”数组,并偶尔遇到排队错误的情况,(对我来说听起来像是台球/斯诺克:)。
  • OpenMP 有一个锁定例程omp_{init,destroy,set,unset,test}_lock。如果您的操作很简单,另一种选择是使用原子
  • 将单个整数推送到线程间队列在任何情况下听起来都不是很有效:(

标签: c multithreading queue openmp


【解决方案1】:

对于保护对一组静态对象的访问的简单情况,可以命名 OpenMP critical 部分:

#pragma omp critical(somename)

在临界区somename 中有一个线程不会阻止另一个线程同时进入临界区othername。未命名的临界区只是一种特殊情况,相当于用一些不透明的系统特定名称来命名该部分。

对于其他一切,都有简单且可嵌套的锁。有关详细信息,请参阅OpenMP specification 中的第 3.3 节 锁定例程

【讨论】:

    猜你喜欢
    • 2014-04-20
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多