Почему в std :: condition_variable notify_all работает быстрее, чем notify_one (при случайных запросах)? - PullRequest
1 голос
/ 21 февраля 2020

Я написал свою реализацию std :: shared_mutex , но на моих тестах она работала в течение нескольких минут, заменила notify_one на notify_all , она начала работать в течение 20 миллисекунд. Это связано с накладными расходами на пробуждение ровно одной условной переменной, поэтому она работает медленнее, чем эта notify_all .

class RWLock {
public:
    template <class Func>
    void Read(Func func) {
        std::unique_lock<std::mutex> lock(mutex_);
        no_writer_.wait(lock, [this] { return !write_; });
        ++read_cnt_;
        lock.unlock();

        try {
            func();
        } catch (...) {
            End();
            throw;
        }
        End();
    }

    template <class Func>
    void Write(Func func) {
        std::unique_lock<std::mutex> lock(mutex_);
        no_readers_.wait(lock, [this] { return read_cnt_ == 0; });

        write_ = true;
        try {
            func();
        } catch (...) {
            write_ = false;
            throw;
        }

        write_ = false;

        no_writer_.notify_all();
    }

private:
    std::mutex mutex_;
    std::condition_variable no_writer_;
    std::condition_variable no_readers_;
    int read_cnt_ = 0;
    bool write_ = false;

    void End() {
        mutex_.lock();
        --read_cnt_;
        no_readers_.notify_all();
        mutex_.unlock();
    }
};

1 Ответ

0 голосов
/ 21 февраля 2020

Вы сигнализируете о состоянии, когда мьютекс заблокирован.

Существует общая оптимизация, которую вы можете попробовать: освободите мьютекс перед вызовом notify_one / notify_all.

...