是否可以讓兩個變量自動遞增。我有以下代碼,由於它是一個多處理器,多線程環境,緩存失效成爲性能瓶頸。所以,我正在儘量減少原子操作的數量。原子操作 - C
__sync_add_and_fetch(&var1,1);
__sync_add_and_fetch(&var2,1);
我看到第一個參數是一個指針,是否有可能通過使用結構來實現我的情況?
P.S:我不能使用鎖。
是否可以讓兩個變量自動遞增。我有以下代碼,由於它是一個多處理器,多線程環境,緩存失效成爲性能瓶頸。所以,我正在儘量減少原子操作的數量。原子操作 - C
__sync_add_and_fetch(&var1,1);
__sync_add_and_fetch(&var2,1);
我看到第一個參數是一個指針,是否有可能通過使用結構來實現我的情況?
P.S:我不能使用鎖。
原子操作非常特殊,只提供有限的支持。將它們應用於兩個變量對我來說聽起來不可能。
請注意,它甚至不保證原子操作是真的用resp完成的。動作操作(即機器碼指令)。
走出gcc doc。 5.47 Built-in functions for atomic memory access:
並非所有操作都受所有目標處理器支持。如果目標處理器無法執行特定操作,則會生成警告,並會生成一個外部函數調用。外部函數將與內建函數名稱相同,並帶有一個額外的後綴'_n',其中n是數據類型的大小。
外部函數可能模擬使用互斥量的原子操作。
但我想,這將有可能是「骯髒的黑客」,只有具有一定的侷限性:
如果16位無符號計數器是足夠的,你可以把他們兩個人在一個32位變量,其中c1c2 += 0x00000001
增量一個,c1c2 += 0x00010000
增量其他,和c1c2 += 0x00010001
遞增兩個 或使用原子操作:
/* combined counters c1 and c2 */
static uint32_t c1c2 = 0;
/* count c1 atomically */
__sync_fetch_and_add(&c1c2, 0x00000001);
/* count c2 atomically */
__sync_fetch_and_add(&c1c2, 0x00010000);
/* count c1 AND c2 atomically */
__sync_fetch_and_add(&c1c2, 0x00010001);
這具有用適當的比特移位和屏蔽訪問invidiual計數器值進行組合。
當然,計數器溢出可能是一個問題。對於64位平臺上的兩個32位計數器可能也是如此(考慮到原子操作通常僅適用於「機器字」寬度)。
順便說一句。而谷歌搜索的背景信息,我偶然發現:Why does __sync_add_and_fetch work for a 64 bit variable on a 32 bit system?。我發現原子操作可能需要足夠的變量正確工作的提示(我發現值得一提)。
這可能是爲什麼C11 Atomic Library爲原子變量提供專用類型(例如atomic_uint_least32_t
)的原因。
非常感謝@Scheff。這有很大幫助。 –
這完全取決於變量的實際類型。如果他們是小型的,那麼各種黑客將成爲可能。 – Lundin