某天,某島國上的花生農老G,因為體力漸衰、氣候異常、地緣政治...等因素,種出的花生品質越來越不穩定,於是邀了其他島上的A格斯先生、高手B爾、阿國兄,四人一起組了個互助會。
互助會規定,為了讓每位成員都能得到差不多品質的花生,每次收成季,四位成員不論品質如何,都要收成 K 公斤的花生,摻和在一起後再平分回給四個人,使得成員們能得到品質較為平均的花生。
例如,
若以 KG、KA、KB、K國,代表四個人收成的 K 公斤的花生,那麼根據互助會規定,將四份花生摻和後再平分,大家最後拿到的花生依然是 K 公斤,而每一份裡包含了:
(KG / 4) + (KA / 4) + (KB / 4)+ (K國 / 4)
也就是說,四位成員都拿到品質差不多的花生,每個人都貢獻了四分之一。
了解了互助會規定後,四個人回到各自的島國上種花生,等待收成季時,再用貨輪運送花生。
問題來了,
花生要運去誰的島?
誰幫忙將大家的花生摻和後再平分?
第一年,
他們決定統一將花生運去G島,由老G幫忙將大家的花生摻和再平分回給大家。
但這樣會有幾個問題,
為了花生的品質,老G摸摸鼻子繼續。
第一天,第一艘貨輪卸貨,
第二天,第二艘貨輪卸貨,
第三天,第三艘貨輪卸貨。
(倉庫快爆了,老G火速處理完花生)
第四天,第一艘貨輪出發,
第五天,第二艘貨輪出發,
第六天,第三艘貨輪出發。
一共花了六天,
老G也快燃燒殆盡了。
註:島很近,先不考慮航行時間。
這方法執行了幾次之後,老G逐漸意識到問題。尤其是現在只有四個人,如果之後有更多人加入互助會,這個方法會造成自己巨大的負擔。
「既然其他人和他們的港口都閒閒沒事...」老G思緒一轉,做了個決定。
第二年開始,老G請大家收成後,先在自己島上將花生分平均成四份。
第一天,
大家運送一份給下一個人,同時也會收到前一位運來的花生。港口一進一出,剛好滿載。
阿國疑惑:「我勒?」
老G:「你就從我後面進來。」
阿國:「那我進去囉,看我的... 阿 國 月工...」
「阿...可惡的抬樹蛙...」老G嬌喘一聲,無奈地收下了阿國運來的花生,儘管沒人聽得懂他們的對話。
第二天,
大家把前一天收到的 K/4 公斤花生,
加上自己的 K/4 公斤花生,
裝在一起共 (K + K) / 4 公斤的花生,運給下一個人。
同時也會收到前一位運來的花生。港口一進一出,剛好滿載。
第三天,
大家把前一天收到的 (K + K) / 4 公斤花生,
加上自己的 K/4 公斤花生,
裝在一起共 (K + K + K) / 4 公斤的花生,運給下一個人。
同時也會收到前一位運來的花生。港口一進一出,剛好滿載。
神奇的事發生了,就在大家收到花生時發現,已經拿到了四個人平均的花生!
每個人手上的花生都已經是:
(KG / 4) + (KA / 4) + (KB / 4)+ (K國 / 4)
而且只花了三天!
而且沒有人累慘!
而且沒有人需要準備超大倉庫!
四個人在各自的島上,拿著望遠鏡面面相覷,
「這...這是...」
接著突然興奮地一起大喊:
「環弦歸一!」
坐在辦公室,正在看 PyTorch 官網上 Ring-Allreduce 的範例 的我,突然想起了這個島國花生農的故事...
四個島就是4片GPU,港口就是記憶體頻寬,
倉庫大小就是記憶體大小,人力就是算力資源。
而運送花生的順序,就是GPU交換、同步數據的順序。
原來如此,
「老G終究還是秀了一波啊。」