J'ai une classe d'objets dans une application multithread où chaque thread peut marquer un objet pour le supprimer, puis un thread central de ramasse-miettes supprime effectivement l'objet. Les threads communiquent via des méthodes membres qui accèdent à un bool interne :
class MyObjects {
...
bool shouldBeDeleted() const
{
return m_Delete;
}
void
markForDelete()
{
m_Delete = true;
}
...
std::atomic< bool > m_IsObsolete;
}
Le bool a été transformé en atomique par quelqu'un d'autre dans le passé parce que Thread Sanitizer ne cessait de se plaindre. Cependant, perf suggère maintenant qu'il y a une surcharge de traitement pendant le chargement atomique interne :
cbz x0, 3f4
_ZNKSt13__atomic_baseIbE4loadESt12memory_order():
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
return __atomic_load_n(&_M_i, __m);
add x0, x0, #0x40
86,96 ldarb w0, [x0]
La plateforme cible est GCC, Aarch64 et Yocto Linux.
Maintenant, mes questions sont les suivantes :
-
L'atomique est-il vraiment nécessaire dans ce cas ? La transition du bool est à sens unique (de false à true) sans possibilité de retour en arrière tant que l'objet vit, donc une incohérence signifierait simplement que l'objet est supprimé un peu plus tard, non ?
-
Existe-t-il une alternative à
std::atomic<bool>
qui réduira au silence Thread Sanitizer mais qui est moins coûteux en calcul questd::atomic<bool>
?