首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++版本的循环屏障是什么?

C++版本的循环屏障是什么?
EN

Stack Overflow用户
提问于 2018-01-13 23:34:46
回答 2查看 984关注 0票数 3

在java中,多个线程可以在某个时间点等待所有其他线程,这样它们就不会在所有其他线程完成第一个代码块之前开始新的代码块:

代码语言:javascript
复制
CyclicBarrier barrier = new CyclicBarrier(2);

// thread 1
readA();
writeB();
barrier.await();
readB();
writeA();

// thread 2
readA();
writeB();
barrier.await();
readB();
writeA();

有没有准确或简单的转换成C++的方法?

对于OpenCL,也有类似的指令:

代码语言:javascript
复制
readA();
writeB();
barrier(CLK_GLOBAL_MEM_FENCE);
readB();
writeA();

所以所有的邻居线程都会相互等待,但这只是一个受约束的C实现。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-15 17:11:51

C++ STL没有循环屏障。您可以向标准委员会推荐一个:)

像甲骨文或微软这样的公司可以很快决定将什么添加到他们的语言库中。对于C++来说,人们必须达成一致,这可能需要一段时间。

256个线程是很多的。与所有与性能相关的问题一样,您需要度量代码以做出明智的决策。对于256个线程,我很想使用由第11个屏障同步的10个屏障。你需要测量才能知道这是否真的更好。

看看我的循环屏障的C++实现,灵感来自于Java。我几年前写的。它是基于我在http://studenti.ing.unipi.it/~s470694/a-cyclic-thread-barrier/找到的其他人的(buggy)代码(链接不再起作用了……)代码非常简单(不需要信任我)。当然,它是原样的,没有任何保证。

代码语言:javascript
复制
// Modeled after the java cyclic barrier.
// Allows n threads to synchronize.
// Call Break() and join your threads before this object goes out of scope
#pragma once

#include <mutex>
#include <condition_variable>


class CyclicBarrier
{
public:
    explicit CyclicBarrier(unsigned numThreads)
        : m_numThreads(numThreads)
        , m_counts{ 0, 0 }
        , m_index(0)
        , m_disabled(false)
    { }

    CyclicBarrier(const CyclicBarrier&) = delete;
    CyclicBarrier(CyclicBarrier &&) = delete;
    CyclicBarrier & operator=(const CyclicBarrier&) = delete;
    CyclicBarrier & operator=(CyclicBarrier &&) = delete;

    // sync point
    void Await()
    {
        std::unique_lock<std::mutex> lock(m_requestsLock);
        if (m_disabled)
            return;

        unsigned currentIndex = m_index;
        ++m_counts[currentIndex];

        // "spurious wakeup" means this thread could wake up even if no one called m_condition.notify!
        if (m_counts[currentIndex] < m_numThreads)
        {
            while (m_counts[currentIndex] < m_numThreads)
                m_condition.wait(lock);
        }
        else
        {
            m_index ^= 1; // flip index
            m_counts[m_index] = 0;
            m_condition.notify_all();
        }
    }

    // Call this to free current sleeping threads and prevent any further awaits.
    // After calling this, the object is no longer usable.
    void Break()
    {
        std::unique_lock<std::mutex> lock(m_requestsLock);
        m_disabled = true;
        m_counts[0] = m_numThreads;
        m_counts[1] = m_numThreads;
        m_condition.notify_all();
    }

private:
    std::mutex     m_requestsLock;
    std::condition_variable m_condition;
    const unsigned m_numThreads;
    unsigned       m_counts[2];
    unsigned       m_index;
    bool           m_disabled;
};
票数 3
EN

Stack Overflow用户

发布于 2019-09-15 07:42:25

你可以在boost库中找到它,它被称为barrier,并且没有等待超时选项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48241351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档