[英]WinAPI _Interlocked* intrinsic functions for char, short
我需要在char或short上使用_Interlocked ***函數,但是它需要長指針作為輸入。 似乎有功能_InterlockedExchange8,我看不到任何文檔。 看起來這是未記錄的功能。 另外,編譯器無法找到_InterlockedAdd8函數。 我將不勝感激有關該功能的任何信息,使用/不使用的建議以及其他解決方案。
更新1
我將嘗試簡化問題。 我該如何進行這項工作?
struct X
{
char data;
};
X atomic_exchange(X another)
{
return _InterlockedExchange( ??? );
}
我看到兩種可能的解決方案
_InterlockedExchange8
another
,進行交換並將結果投放回X 第一個顯然是不好的解決方案。 第二個看起來更好,但是如何實現呢?
更新2
您如何看待這樣的事情?
template <typename T, typename U>
class padded_variable
{
public:
padded_variable(T v): var(v) {}
padded_variable(U v): var(*static_cast<T*>(static_cast<void*>(&v))) {}
U& cast()
{
return *static_cast<U*>(static_cast<void*>(&var));
}
T& get()
{
return var;
}
private:
T var;
char padding[sizeof(U) - sizeof(T)];
};
struct X
{
char data;
};
template <typename T, int S = sizeof(T)> class var;
template <typename T> class var<T, 1>
{
public:
var(): data(T()) {}
T atomic_exchange(T another)
{
padded_variable<T, long> xch(another);
padded_variable<T, long> res(_InterlockedExchange(&data.cast(), xch.cast()));
return res.get();
}
private:
padded_variable<T, long> data;
};
謝謝。
制作8位和16位互鎖功能非常容易,但是WinAPI中不包含這些功能的原因是由於IA64可移植性。 如果要支持Win64,則匯編器不能內聯,因為MSVC不再支持它。 作為使用MASM64的外部功能單元,它們將不如內聯代碼或內在函數快,因此,明智的方法是研究促進使用32位和64位原子運算的算法。
互鎖的API實現示例: intrin.asm
為什么要使用較小的數據類型? 因此,您可以在一小塊存儲空間中容納其中的一堆嗎? 這只會導致錯誤的共享和緩存行爭用。
無論您使用鎖定算法還是無鎖定算法,理想的情況是將數據分成至少128個字節(或CPU上的高速緩存行大小)的塊,一次僅由一個線程使用。
好吧,您必須使用可用的功能。 _InterlockedIncrement
和`_InterlockedCompareExchange在16位和32位版本中可用(后者在64位版本中也可用),也許其他一些互鎖的內在函數也可以在16位版本中使用,但是InterlockedAdd似乎沒有是,而且似乎根本沒有字節大小的互鎖的內在函數/函數。
所以...您需要退后一步,弄清楚如何在沒有IntrinsicAdd8
情況下解決問題。
無論如何,為什么要使用單個字節? 除非您有充分的理由使用較小的對象,否則請堅持使用int
大小的對象。
創建新的答案,因為您的編輯稍微改變了一些內容:
- 使用_InterlockedExchange8
- 長時間投放另一個,進行交換並將結果投放回X
第一個根本行不通。 即使該函數存在,它也允許您一次原子更新一個字節。 這意味着整個對象將通過一系列步驟( 不是原子的)進行更新。
除非X
是long
尺寸的POD類型,否則第二個也不起作用。 (並且除非它在sizeof(long)
邊界上對齊,並且除非它與long
大小相同)
為了解決此問題,您需要縮小X
類型。 首先,當然可以保證是POD類型嗎? 否則,您將面臨一個完全不同的問題,因為您不能安全地將非POD類型視為原始內存字節。
其次, X
可能有什么尺寸? 互鎖功能可以處理16、32,並且視情況而定,可以處理64甚至128位的寬度。
這涵蓋了您可能遇到的所有情況嗎?
如果不是,您可能必須放棄這些原子操作,並選擇普通的舊鎖。 鎖定互斥鎖以確保一次只有一個線程觸摸這些對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.