接著上周未完的話題 避不開的數據拷貝。
既然處理器是通用機器,就沒有專屬數據,所以數據都要從別處調來,這就涉及到了數據搬運,就有了外設的概念。由于不同外設和處理器一起共享數據存儲,時間會花在兩方面:
- 時間會花在檢索自己需要的數據上,這是算法和數據結構的領域;
- 時間會花在數據搬運上,這是拓撲,總線,網絡,協議的領域;
“盡量不拷貝” 和 “盡量不傳輸數據” 都是盡量不移動數據的實例,而不是醉心于讓拷貝和傳輸變得更快。為了不移動數據卻又能使用數據,要將思路轉換為傳遞控制信號或直接傳遞結果,讓數據保持在 “原地”。 這需要更多的通路組織更智能的網絡。
近年來如日中天的零拷貝,設備內存,片商存儲等概念值得一提,但在軟件領域,其實人們一直在恪守這些信念。不外乎兩個觀點:
- 內存觀點,固定 buffer,比如統一往一個 buffer-ring 里送;
- 程序觀點,離散 buffer,比如將離散的 buffer 串成一個 queue;
總之都是數據能不動就不動,實在要動就少動,如果有誰寫了一個程序,頻繁做 memcpy,勢必要被優化掉,不管是針對程序,還是針對人。
可以審視從初學編程到使用 Linux 內核的 splice/tee,基本就是上圖的過程,從一開始果真把 queue 當成一個實體 queue,copy 內存往里排隊,到最后直接在兩個 fd 之間非 copy 傳遞數據,見證了逐漸讓數據不移動的過程。
同理,當外設能力反超 CPU,而軟件成為瓶頸后,外設硬件當然要走一遍同樣的路,近年來的 Device Memory TCP 就是其中一例:
其它實例幾乎同理。
還有一個問題,如果必須要搬運,數據搬運過程中為什么需要 buffer,為什么不能一鏡到底,推而廣之,為什么要接力,轉介。這就要說到通用計算機處理數據的兩類方式:
- 流水線提高吞吐;
- 并行化提高吞吐;
總之要有資源,且要資源全部動起來,這是一種通用資源組織理念,無論對硬件還是軟件。
本質上還是因為通用機器以數據為中心,通用機器的數據都從別處搬來,效率高低取決于搬運的方式,如果有搬運和處理部件閑置,就一定要想辦法將它用起來。
定量講,如果增加一倍的通用處理資源,理論上應該增加一倍的吞吐。舉例說明,將數據從 A 搬到 B:
可見并行方式就是一鏡到底,這并不是問題的核心所在。問題的核心在于分割時間還是分割空間,本質上還是如何在時空展開的問題,這就涉及到數據的語義。
如果數據是嚴格保序的,通用機器需無條件滿足該約束,典型例子是通用處理器,即 CPU,它的處理資源必須在時間維度分割成流水線,作為數據的串行指令在其中接力通過。另一個對面的例子,內存數據是不保序的地址映射,因此它是并行結構,每一個 bit 都有一條地址線和數據線傳輸該 bit,這些線在空間維度并在一起。
這樣看來,串行指令通過流水線執行,而數據則通過并行通道映射到目的地,似乎一想就通,但當真正傳輸數據而不僅僅是內存和 CPU 交互時,卻紛紛拒絕并行,接受 stream 抽象,分層模型下 “縱然在 byte 級別存在 byte stream,但在 bit 級別依然并行傳輸” 的內存操作,等價為 “縱然在 byte 級別存在 byte stream,但在 packet 級別依然并行傳輸” 被忽視,也許是 packet 出現在 byte stream 之后,IP 從 TCP 分離而來之故,但 PCIe,USB 也是串行。
否則,若信道不識 stream,像內存地址般映射,并行傳輸就是自然而然的選擇。
現如今,除了內存,芯片內部總線采用并行策略外,幾乎都選擇了串行,從大尺度的 TCP/IP,到微尺度的 PCIe,明確的理由似乎又要回到早期串行,并行之爭里去尋址,不外乎:
- 并行信號時鐘同步困難,時鐘偏移,線路干擾,布線成本高;
- 串行時鐘精準同步,抗干擾強,線路少,成本低,適合長距離;
把這些往大尺度 TCP/IP 延申,也能解釋 MPTCP 的實現粒度為什么做不細,本質上是一回事。所以,最終的通用策略是:
- 傳輸網絡以并行的方式構建,業務數據在其特定的某條路徑上串行傳輸。
但這只是通用策略,值得注意的是例外,若并行劣勢均克服,串行就沒優勢了,這也是我認可數據中心網絡并行多路徑傳輸的原因:
- 拓撲規則,ECMP 路徑一致,RTT 短,同步存儲開銷小,負載分擔,擁塞均衡。
總之,數據中心傳輸可像內存和內部總線那般并行,但其它場景不具備這特征,不管是廣域網,USB,PCIe,還是 nvlink。更微觀意義上,串行并行依然保持著嵌套,PCIe,nvlink 雖串行,但它們均采用多通道并行捆綁實現更高的帶寬,整個數據搬運結構在全局看來依然維持著規整。
盡量不搬運數據,非要少量搬運,上面介紹了如何高效搬運。進一步優化思路就很明確,像以往專用設備那樣獨占數據,讓數據和處理一體化,就滑向蹺蹺板的另一端了。
浙江溫州皮鞋濕,下雨進水不會胖。