manipulation de bit unique

Est-il possible d’obtenir juste un bit d’un int en C et de le retourner sans lire l’int complet et l’écrire en mémoire?

contexte: essayer d’éviter trop de verrous / délockings dans pthread.

Vous ne pouvez pas lire un seul bit de la mémoire, mais vous ne pouvez pas forcer le processeur à lire un seul octet. Il lit toujours une ligne de cache complète, qui peut avoir différentes tailles pour différents processeurs.

Mais du sharepoint vue de la langue, vous pouvez utiliser les champs de bits http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html

Autant que je sache, l’unité d’opération la plus basse est l’octet. Peut-être que vous pouvez diviser l’int en octets et lire l’octet requirejs dans le mot et ne changer que celui-là.

Pourquoi, même si vous pouviez lire un bit de la mémoire, vous aurez toujours besoin de verrouiller pour vous assurer que tout est en sécurité.

Soit utilisez le plus petit type qui puisse être traité de manière atomique ( char convient à toute architecture rationnelle, mais certaines jonques RISC ne peuvent pas fonctionner de manière atomique sur des octets individuels) et acceptez le fait que vous gaspillez de l’espace, utilisez un verrou ou utilisez le code atomique approprié. primitives (dans les types asm, gcc, ou C1x _Atomic ) pour l’arithmétique atomique sur des bits individuels.

Voici comment le faire 50 fois plus vite que papy mutex (nous avons fait des tests sur ce genre de chose). Utilisez les opérations atomiques gcc. Vous pouvez également utiliser les opérations atomiques linux si votre version les inclut.

 typedef union _foo { struct { unsigned int a:1, b:6, q:2; } Data; unsigned int n32; } TFoo; TFoo _GlobalFoo; SomeFuncThatChangesFoo_A(int fNewA) { TFoo Old, New; while(1) { // get a copy of the current state Old.n32 = _GlobalFoo.n32; New.n32 = Old.n32; New.Data.a = fNewA; // compare and swap is the atomic operation. // if _GlobalFoo hasn't changed since we copied it to "Old", then change _GlobalFoo to "New". // __sync_bool_compare_and_swap works on basic types (8 bit, 16 bit, 32 bit, 64 bit, 128 bit // depending upon architecture), which is why there is a union overlaying the 32 bit n32 over // the actual data that the program uses, Data. if (__sync_bool_compare_and_swap(_GlobalFoo.n32, Old.n32, New.n32)) break; // successfully changed // if we get here, the global was changed by another thread, so we just loop back, get the new value // and try again. } // concurrency loop } 

Les threaders astucieux pourraient penser que la ligne “Old.n32 = _GlobalFoo.n32;” pourrait copier des déchets dans une course si le compilateur choisissait une méthode non atomique pour effectuer la copie. Cependant, __sync_bool_compare_and_swap échouerait simplement à cause d’une mauvaise copie de l’état actuel, ainsi aucun dommage ne serait causé.

à votre santé.

Cela pourrait être possible, mais uniquement de manière non portable, non standard et uniquement si votre plate-forme le prend en charge. Certaines CPU ARM (Cortex-M3 et M4 par exemple) implémentent une «bande de bits» qui fournit un adressage au niveau du bit aux régions de l’espace d’adressage.

Mais en général, la plus petite unité de lecture / écriture (ou, de manière équivalente, la plus petite unité adressable) est un caractère.