日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Linus:為何對(duì)象引用計(jì)數(shù)必須是原子的

Linus大神又在rant了!這次的吐槽對(duì)象是時(shí)下很火熱的并行技術(shù)(parellism),并直截了當(dāng)?shù)乇硎静⑿杏?jì)算是浪費(fèi)所有人時(shí)間(“The whole “l(fā)et’s parallelize” thing is a huge waste of everybody’s time.”)。大致意思是說(shuō)亂序性能快、提高緩存容量、降功耗。當(dāng)然筆者不打算正面討論并行的是是非非(過(guò)于宏偉的主題),因?yàn)長(zhǎng)inus在另一則帖子中舉了對(duì)象引用計(jì)數(shù)(reference counting)的例子來(lái)說(shuō)明并行的復(fù)雜性。

在Linus回復(fù)之前有人指出對(duì)象需要鎖機(jī)制的情況下,引用計(jì)數(shù)的原子性問(wèn)題:

Since it is being accessed in a multi-threaded way, via multiple access paths, generally it needs its own mutex — otherwise, reference counting would not be required to be atomic and a lock of a higher-level object would suffice.

由于(對(duì)象)通過(guò)多線程方式及多種獲取渠道,一般而言它需要自身維護(hù)一個(gè)互斥鎖——否則引用計(jì)數(shù)就不要求是原子的,一個(gè)更高層次的對(duì)象鎖足矣。

而Linus不那么認(rèn)為:

The problem with reference counts is that you often need to take them *before* you take the lock that protects the object data.

引用計(jì)數(shù)的問(wèn)題在于你經(jīng)常需要在對(duì)象數(shù)據(jù)上鎖保護(hù)之前完成它。

The thing is, you have two different cases:

問(wèn)題有兩種情況:

- object *reference* 對(duì)象引用

- object data 對(duì)象數(shù)據(jù)

and they have completely different locking.

它們鎖機(jī)制是完全不一樣的。

Object data locking is generally per-object. Well, unless you don’t have huge scalability issues, in which case you may have some external bigger lock (extreme case: one single global lock).

對(duì)象數(shù)據(jù)保護(hù)一般是一個(gè)對(duì)象擁有一個(gè)鎖,假設(shè)你沒(méi)有海量擴(kuò)展性問(wèn)題,不然你需要一些外部大一點(diǎn)的鎖(極端的例子,一個(gè)對(duì)象一個(gè)全局鎖)。

But object *referencing* is mostly about finding the object (and removing/freeing it). Is it on a hash chain? Is it in a tree? Linked list? When the reference count goes down to zero, it’s not the object data that you need to protect (the object is not used by anything else, so there’s nothing to protect!), it’s the ways to find the object you need to protect.

但對(duì)象引用主要關(guān)于對(duì)象的尋找(移除或釋放),它是否在哈希鏈,一棵樹(shù)或者鏈表上。當(dāng)對(duì)象引用計(jì)數(shù)降為零,你要保護(hù)的不是對(duì)象數(shù)據(jù),因?yàn)閷?duì)象沒(méi)有在其它地方使用,你要保護(hù)的是對(duì)象的尋找操作。

And the lock for the lookup operation cannot be in the object, because – by definition – you don’t know what the object is! You’re trying to look it up, after all.

而且查詢(xún)操作的鎖不可能在對(duì)象內(nèi)部,因?yàn)楦鶕?jù)定義,你還不知道這是什么對(duì)象,你在嘗試尋找它。

So generally you have a lock that protects the lookup operation some way, and the reference count needs to be atomic with respect to that lock.

因此一般你要對(duì)查詢(xún)操作上鎖,而且引用計(jì)數(shù)相對(duì)那個(gè)鎖來(lái)說(shuō)是原子的(譯者注:查詢(xún)鎖不是引用計(jì)數(shù)所在的對(duì)象所有,不能保護(hù)對(duì)象引用計(jì)數(shù),后面會(huì)解釋為何引用計(jì)數(shù)變更時(shí)其所在對(duì)象不能上鎖)。

And yes, that lock may well be sufficient, and now you’re back to non-atomic reference counts. But you usually don’t have just one way to look things up: you might have pointers from other objects (and that pointer is protected by the object locking of the other object), but there may be multiple such objects that point to this (which is why you have a reference count in the first place!)

當(dāng)然這個(gè)鎖是充分有效的,現(xiàn)在假設(shè)引用計(jì)數(shù)是非原子的,但你常常不僅僅使用一種方式來(lái)查詢(xún):你可能擁有其它對(duì)象的指針(這個(gè)指針又被其它對(duì)象的對(duì)象鎖給保護(hù)起來(lái)),但同時(shí)還會(huì)有多個(gè)對(duì)象指向它(這就是為何你第一時(shí)間需要引用計(jì)數(shù)的理由)。

See what happens? There is no longer one single lock for lookup. Imagine walking a graph of objects, where objects have pointers to each other. Each pointer implies a reference to an object, but as you walk the graph, you have to release the lock from the source object, so you have to take a new reference to the object you are now entering.

看看會(huì)發(fā)生什么?查詢(xún)不止存在一個(gè)鎖保護(hù)。你可以想象走過(guò)一張對(duì)象流程圖,其中對(duì)象存在指向其它對(duì)象的指針,每個(gè)指針暗含了一次對(duì)象引用,但當(dāng)你走過(guò)這個(gè)流程圖,你必須釋放源對(duì)象的鎖,而你進(jìn)入新對(duì)象時(shí)又必須增加一次引用。

And in order to avoid deadlocks, you can not in the general case take the lock of the new object first – you have to release the lock on the source object, because otherwise (in a complex graph), how do you avoid simple ABBA deadlock?

而且為了避免死鎖,你一般不能立即對(duì)新對(duì)象上鎖——你必須釋放源對(duì)象的鎖,否則在一個(gè)復(fù)雜流程圖里,你如何避免ABBA死鎖(譯者注:假設(shè)兩個(gè)線程,一個(gè)是A->B,另一個(gè)B->;A,當(dāng)線程一給A上鎖,線程二給B上鎖,此時(shí)兩者誰(shuí)也無(wú)法釋放對(duì)方的鎖)?

So atomic reference counts fix that. They work because when you move from object A to object B, you can do this:

原子引用計(jì)數(shù)修正了這一點(diǎn),當(dāng)你從對(duì)象A到對(duì)象B,你會(huì)這樣做:

(a) you have a reference count to A, and you can lock A

對(duì)象A增加一次引用計(jì)數(shù),并上鎖。

(b) once object A is locked, the pointer from A to B is stable, and you know you have a reference to B (because of that pointer from A to B)

對(duì)象A一旦上鎖,A指向B的指針就是穩(wěn)定的,于是你知道你引用了對(duì)象B。

(c) but you cannot take the object lock for B (ABBA deadlock) while holding the lock on A

但你不能在對(duì)象A上鎖期間給B上鎖(ABBA死鎖)。

(d) increment the atomic reference count on B

對(duì)象B增加一次原子引用計(jì)數(shù)。

(e) now you can drop the lock on A (you’re “exiting” A)

現(xiàn)在你可以扔掉對(duì)象A的鎖(退出對(duì)象A)。

(f) your reference count means that B cannot go away from under you despite unlocking A, so now you can lock B.

對(duì)象B的原子引用計(jì)數(shù)意味著即使給A解鎖期間,B也不會(huì)失聯(lián),現(xiàn)在你可以給B上鎖。

See? Atomic reference counts make this kind of situation possible. Yes, you want to avoid the overhead if at all possible (for example, maybe you have a strict ordering of objects, so you know you can walk from A to B, and never walk from B to A, so there is no ABBA deadlock, and you can just lock B while still holding the lock on A).

看見(jiàn)了嗎?原子引用計(jì)數(shù)使這種情況成為可能。是的,你想盡一切辦法避免這種代價(jià),比如,你也許把對(duì)象寫(xiě)成嚴(yán)格順序的,這樣你可以從A到B,絕不會(huì)從B到A,如此就不存在ABBA死鎖了,你也就可以在A上鎖期間給B上鎖了。

But if you don’t have some kind of forced ordering, and if you have multiple ways to reach an object (and again – why have reference counts in the first place if that isn’t true!) then atomic reference counts really are the simple and sane answer.

但如果你無(wú)法做到這種強(qiáng)迫序列,如果你有多種方式接觸一個(gè)對(duì)象(再一次強(qiáng)調(diào),這是第一時(shí)間使用引用計(jì)數(shù)的理由),這樣,原子引用計(jì)數(shù)就是簡(jiǎn)單又理智的答案。

If you think atomic refcounts are unnecessary, that’s a big flag that you don’t actually understand the complexities of locking.

如果你認(rèn)為原子引用計(jì)數(shù)是不必要的,這就大大說(shuō)明你實(shí)際上不了解鎖機(jī)制的復(fù)雜性。

Trust me, concurrency is hard. There’s a reason all the examples of “l(fā)ook how easy it is to parallelize things” tend to use simple arrays and don’t ever have allocations or freeing of the objects.

相信我,并發(fā)設(shè)計(jì)是困難的。所有關(guān)于“并行化如此容易”的理由都傾向于使用簡(jiǎn)單數(shù)組操作做例子,甚至不包含對(duì)象的分配和釋放。

People who think that the future is highly parallel are invariably completely unaware of just how hard concurrency really is. They’ve seen Linpack, they’ve seen all those wonderful examples of sorting an array in parallel, they’ve seen all these things that have absolutely no actual real complexity – and often very limited real usefulness.

那些認(rèn)為未來(lái)是高度并行化的人一成不變地完全沒(méi)有意識(shí)到并發(fā)設(shè)計(jì)是多么困難。他們只見(jiàn)過(guò)Linpack,他們只見(jiàn)過(guò)并行技術(shù)中關(guān)于數(shù)組排序的一切精妙例子,他們只見(jiàn)過(guò)一切絕不算真正復(fù)雜的事物——對(duì)真正的用處經(jīng)常是非常有限的。

(譯者注:當(dāng)然,我無(wú)意借大神之口把技術(shù)宗教化。實(shí)際上Linus又在另一篇帖子中綜合了對(duì)并行的評(píng)價(jià)。)

Oh, I agree. My example was the simple case. The really complex cases are much worse.

哦,我同意。我的例子還算簡(jiǎn)單,真正復(fù)雜的用例更糟糕。

I seriously don’t believe that the future is parallel. People who think you can solve it with compilers or programming languages (or better programmers) are so far out to lunch that it’s not even funny.

我嚴(yán)重不相信未來(lái)是并行的。有人認(rèn)為你可以通過(guò)編譯器,編程語(yǔ)言或者更好的程序員來(lái)解決問(wèn)題,他們目前都是神志不清,沒(méi)意識(shí)到這一點(diǎn)都不有趣。

Parallelism works well in simplified cases with fairly clear interfaces and models. You find parallelism in servers with independent queries, in HPC, in kernels, in databases. And even there, people work really hard to make it work at all, and tend to expressly limit their models to be more amenable to it (eg databases do some things much better than others, so DB admins make sure that they lay out their data in order to cater to the limitations).

并行計(jì)算可以在簡(jiǎn)化的用例以及具備清晰的接口和模型上正常工作。你發(fā)現(xiàn)并行在服務(wù)器上獨(dú)立查詢(xún)里,在高性能計(jì)算(High-performance computing)里,在內(nèi)核里,在數(shù)據(jù)庫(kù)里。即使如此,人們還得花很大力氣才能使它工作,并且還要明確限制他們的模型來(lái)盡更多義務(wù)(例如數(shù)據(jù)庫(kù)要想做得更好,數(shù)據(jù)庫(kù)管理員得確保數(shù)據(jù)得到合理安排來(lái)迎合局限性)。

Of course, other programming models can work. Neural networks are inherently very parallel indeed. And you don’t need smarter programmers to program them either..

當(dāng)然,其它編程模型倒能派上用場(chǎng),神經(jīng)網(wǎng)絡(luò)(neural networking)天生就是非常并行化的,你不需要更聰明的程序員為之寫(xiě)代碼。

參考資料

  • Real World Technologies:Linus常去“灌水”的一個(gè)論壇,討論未來(lái)機(jī)器架構(gòu)(看名字就知道Linus技術(shù)偏好,及其之前對(duì)虛擬化技術(shù)(virtualization)的吐槽)
  • 多線程程序中操作的原子性:解釋為什么i++不是原子操作
  •  Concurrency Is Not Parallelism:Go語(yǔ)言之父Rob Pike幻燈片解釋“并發(fā)”與“并行”概念上的區(qū)別

分享名稱(chēng):Linus:為何對(duì)象引用計(jì)數(shù)必須是原子的
瀏覽地址:http://m.5511xx.com/article/copgdge.html