У меня есть два потока, t1 и t2, которые обращаются к нескольким переменным (целые и двойные), давайте назовем их a, b и c. t1 находится на моем критическом пути и увеличивает / уменьшает эти переменные посредством дорогого сравнения и обмена.
std::atomic<double> a;
std::atomic<double> b;
std::atomic<double> c;
std::atomic<uint32_t> d;
.
.
.
// Extremely-common, critical path thread t1
d++;
while(!a.compare_and_exchange(expectedVal, newVal);
while(!b.compare_and_exchange(expectedVal, newVal);
while(!c.compare_and_exchange(expectedVal, newVal);
t2 встречается редко, но когда это происходит, он добавляет переменные, упомянутые выше, вместе.
// Rare thread, t2
return a + b - c;
На данный момент я использую атомику. Можно ли как-нибудь объявить переменные как неатомарные, потому что в 99,999% случаев они увеличиваются из одного и того же потока, а в «редком потоке» я мог бы использовать барьер памяти, чтобы гарантировать, что я не смогу вернуться a + b - c
пока поток «критического пути» не закончит писать какие-либо магазины?
Это позволило бы мне добавить задержку только в тех случаях, когда редкий поток выполняется.
Я не уверен из твоего вопроса, возможно ли это, но ты мог бы реорганизовать «связь» между своими потоками, чтобы разделить меньшее состояние.
Например, предположим, что они только «общаются» через a + b - c
в том смысле, что только t1 обновляет компоненты по отдельности, а t2 только читает эту конкретную комбинацию. В этом случае вы можете использовать меньше атомных операций, определив a
, b
, а также c
как обычные переменные, и новая переменная, combination
, как атомная переменная. t1 будет затем увеличивать вещи нормально, и будет использовать одну атомную операцию для обновления combination
,