Załóżmy, że mam klasy, który wygląda tak (w rzeczywistości dokładnie tej wielkości):Czy wspólny muteks jest wydajniejszy od atomu o relatywnie dużej strukturze?
class K
{
public:
long long get_x() const; // lock m_mutex in shared/read-only mode
void update(long long w); // lock m_mutex with a unique_lock
private:
long long m_a;
long long m_b;
long long m_c;
long long m_x;
double m_flow_factor;
mutable boost::shared_mutex m_mutex;
};
Jak widać, ten powinien być bezpieczny wątku. Funkcja aktualizacji jest wywoływana przez jeden wątek na raz, nieznany, ale tylko jeden wątek (gwarantowany), ale akcesor może być wywoływany przez kilka wątków w tym samym czasie.
Funkcja Aktualizacja zmienia wszystkie wartości i nazywa się bardzo często (hundread razy na sekundę). Obecna implementacja będzie, jak można się domyślić, bardzo blokuje.
Rozważałem użycie std :: atomic, aby uniknąć blokad i potencjalnie uczynić ten kod bardziej wydajnym. Jednak naprawdę potrzebuję funkcji aktualizacji, aby zaktualizować wartości razem. Dlatego jestem rozważa robi coś takiego zamiast:
class K
{
public:
long long get_x() const
{ return data.load().x; }
void update(long long w)
{
auto data_now = data.load();
// ... work with data_now
data.store(data_now);
}
private:
struct Data {
long long a;
long long b;
long long c;
long long x;
double flow_factor;
};
std::atomic<Data> data;
};
Moje obecne rozumienie std :: atomowa jest to, że nawet jeśli ten kod jest bardziej czytelny niż poprzedni (ponieważ nie mam deklaracje blokady wszędzie), jako struktura K :: Data jest "duża", std :: atomowa zostanie zaimplementowana z normalną blokadą mutex (więc i tak nie powinna być szybsza niż moja początkowa implementacja).
Czy mam rację?
Nie wiedziałem o tym dla shared_mutex ... dzięki za informację! – Klaim