2013-12-16 24 views
3

如果我有一個整數x,下列哪些語句在iPhone上的ARM架構上是原子的?哪些整數操作在ios/arm平臺上是原子的?

int x; 
int y; 
x = 92; // . . . . . . A 
x++;  // . . . . . . B 
y = ++x; // . . . . . . C 
printf("x = %d\n", x); // D 

我知道,在i386平臺上,語句A,B和D是原子的,而C不是。我很確定C在iOS中不是原子的。我懷疑基本的加載和存儲操作(D和A)在iOS中也是原子的,但我不確定。有誰知道更多?

它是如何與16位和8位值?或者iPhone 5S上的64位值和iPhone 5及更低版本上的64位值?

(如果答案是,因爲我懷疑...有任何平臺,基本負載和存儲操作不是原子?)

+0

我不太確定B是在i386原子:)你試圖做什麼?你可以使用操作系統同步原語嗎?例如OSAtomic ...函數系列https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW14 – yurish

+0

他們不是原子的,他們創造了一個完整的記憶障礙。但是否則他們是,我想。例如如果x是23,一個線程通過調用x ++來更改它,而另一個線程同時訪問x,那麼其他線程在加載x時將得到23或24,但不是-817376或21. – Michael

+0

我可能是錯的,但認爲原子性是語言的東西而不是平臺。當你說上述操作是原子的時候,你依賴於編譯器的實現細節。 – yurish

回答

2

你不給就xy聲明足夠的上下文。如果函數中有本地人,那麼他們將被分配到寄存器,而其他線程不能觸摸它們。所以我認爲你的意思是他們是全球性的(或者至少是靜態的)。

ARM是一個加載存儲體系結構。它沒有內存內存說明。所以真的只有線A/D是原子。你無條件寫下價值。它不是與另一個線程相關的。如果一個線程寫入92,而另一個線程寫入29,那麼將無法知道沒有某種類型的互斥鎖寫入的內容。

Early ARM cpus have swp;但大多數iOS產品將使用ldrexstrex。您必須使用這些說明進行任何種類的原子更新。

ARM可以一次寫入8/16/32/64位,並且大多數系統設計將具有同步的高速緩存,以便另一個CPU可以看到一個CPU的寫入。環形緩衝區結構可以與生產者/消費者一起使用,其中只有一個CPU寫入環形頭,另一個CPU寫入環形尾部;也就是說,這將是一個原子結構,您可以在沒有swpldrexstrex的情況下使用。

如果你手動分配一個64位的值,你可能會搞砸了。你將不得不努力做到這一點。例如,如果在64位值的高/低32位之間發生頁面錯誤。顯然,取決於CPU類型,未對齊的值也可能有問題。如果你正常的聲明,它們應該被編譯器很好的對齊。這也可以通過未對齊的 32位和16位值來實現。 iOS可能會使這些訪問看起來原子爲用戶空間。一般來說,如果你依賴原子行爲,你不應該做任何奇怪的強制轉換,並正常地聲明變量。

編輯:

(如果答案是,因爲我懷疑...有任何平臺,基本負載和存儲操作不是原子?)

是的,有許多平臺的大值加載/存儲不是原子的;特別是對於所有數據類型。實際上,大多數CPU至少有8位(儘管有4位CPU),所以加載和存儲通常是原子的。對於較小的CPU,較大值的加載/存儲可能需要幾個週期。在這些情況下,編譯器將花費多個週期來更新值。這是sig_atomic_t背後的想法;它是一個可以自動更新的可變大小。 sig_atomic_t應在所有Posix systems上可用,但在普通C99中沒有一般保證。 C11添加了_Atomic類型限定符。

+0

謝謝!是的,我的意思是全局或靜態變量。 「物品A/D是原子」是什麼意思? A/D代表什麼?我的理解是否正確:如果x是92,一個線程將其更改爲29,那麼另一個線程將會看到92或29,但不是完全不相關的值?知道緩存有多大可能會變得很有趣?一切事情總是在幾毫秒內或幾秒鐘內同步,或者偶爾會同步甚至更長時間? – Michael

+0

是的。那是對的。也許值'0xffee0000UL'和'0xddccUL'會更好。沒有辦法看到'0xffeeddccUL'或只是'0x0UL'或其他組合。 'str'和'ldr'是一個單獨的指令,不中斷運行。在多CP​​U設計中,高速緩存/內存被保留並廣播,因此不同的CPU看不到不同的值。 * A/D *是您的物品/行* A *和* D *。 –