簡體   English   中英

WinAPI _Interlocked *內在函數,用於char,簡稱

[英]WinAPI _Interlocked* intrinsic functions for char, short

我需要在char或short上使用_Interlocked ***函數,但是它需要長指針作為輸入。 似乎有功能_InterlockedExchange8,我看不到任何文檔。 看起來這是未記錄的功能。 另外,編譯器無法找到_InterlockedAdd8函數。 我將不勝感激有關該功能的任何信息,使用/不使用的建議以及其他解決方案。

更新1

我將嘗試簡化問題。 我該如何進行這項工作?

struct X
{
    char data;
};

X atomic_exchange(X another)
{
    return _InterlockedExchange( ??? );
}

我看到兩種可能的解決方案

  1. 使用_InterlockedExchange8
  2. 長時間投放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

第一個根本行不通。 即使該函數存在,它也允許您一次原子更新一個字節。 這意味着整個對象將通過一系列步驟( 不是原子的)進行更新。

除非Xlong尺寸的POD類型,否則第二個也不起作用。 (並且除非它在sizeof(long)邊界上對齊,並且除非它與long大小相同)

為了解決此問題,您需要縮小X類型。 首先,當然可以保證是POD類型嗎? 否則,您將面臨一個完全不同的問題,因為您不能安全地將非POD類型視為原始內存字節。

其次, X可能有什么尺寸? 互鎖功能可以處理16、32,並且視情況而定,可以處理64甚至128位的寬度。

這涵蓋了您可能遇到的所有情況嗎?

如果不是,您可能必須放棄這些原子操作,並選擇普通的舊鎖。 鎖定互斥鎖以確保一次只有一個線程觸摸這些對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM