2014-06-27 55 views
2

我有一臺運行64位處理器的64位機器,但我的應用程序是32位。閱讀或寫作雙保證是原子?我只是在談論作業和閱讀。 32位程序如何影響這個過程?當其他線程在給定規範中寫入時,讀者是否可以從雙精度值讀取部分值?是讀取和寫入雙重保證在64位英特爾處理器上原子的變量?

+1

不,_「[讀取和寫入\ [... \] long,ulong,double和decimal以及用戶定義的類型不保證是原子](http:// msdn。 microsoft.com/en-us/library/aa691278%28VS.71%29.aspx)"_。另請參閱[是否爲Volatile.Read/Volatile.Write for「double」atomic?](http://stackoverflow.com/questions/12435325/does-volatile-read-volatile-write-for-double-atomic)。 – CodeCaster

+0

@CodeCaster這是來自VS03(不VS13)和C#語言規範。如果需要,64位CLR可以提供額外的保證。 – usr

+0

如果double對齊(即在8字節的邊界上),那麼讀取和寫入是原子的。在32位和64位架構上都是如此。 –

回答

3

編號A double可以很容易地跨越L1緩存線的邊界,需要多個總線週期將兩塊膠粘在一起。在C#中一個非常現實的問題是,32位CLR僅提供了對齊保證4.這些未對齊的訪問不僅不是原子的,而且由於處理器需要進行混洗,所以它們也很昂貴。使用雙精度的代碼可以有3個不同的定時,如果雙精度偶然對齊到8,則速度快;當它與4偏移但仍然在L1高速緩存線內時速度減慢兩倍;當跨越一個偏移量時偏移速度慢三倍緩存行。當垃圾收集器壓縮堆並移動double時,這樣的程序可以隨機碰到這些模式之一。對非常感興趣,綜合測試程序可以很容易地錯過這種故障模式。

perf問題是double []在大對象堆中分配得早得多的正常核心原因。 LOH提供了一個8保證的路線。正常的規則是對象> = 85,000字節,對於32位模式中的double [],它是8,000字節(數組中有1000個元素)。

必須如果您需要原子性保證,請使用Interlocked.Exchange()。我應該發佈免責聲明,即原子性是一個非常弱的保證,並且在需要時不能替代正確的鎖定。

+0

雙打不對齊是真的嗎?這必須對性能產生驚人的影響。 –

+0

我發現了這個硬路™:)而且更喜歡x64的抖動。 –

+0

我使用'GCAlloc'作爲'gch = GCHandle.Alloc(data,GCHandleType.Pinned)'分配一個大約100到500'雙精度數組'。這是否與預期一致? – Alok

相關問題