分而治之
作為最終示例(你肯定對生動的**開始生厭並希望回頭去鑽研關於比較性、抽象性準則的語言學**),讓我們來做乙個小型超級計算。然後喝個咖啡。我們的超級計算程式是個非常典型的並行處理模型。我們有:
乙個通風機(ventilator)來產生可以並行處理的任務
一組工人(worker)來處理任務
乙個水槽(sink)來**工人處理的結果
事實上,工人執行於超快的機子,沒準是gpu(圖形處理單元)來做困難運算。這是通風機**,生成100個任務,每個任務都是一條訊息告訴工人休眠(sleep)幾毫秒。
taskvent: parallel task ventilator in c
[cpp]
//
// task ventilator
// binds push socket to tcp://localhost:5557
// sends batch of tasks to workers via that socket
//
#include "zhelpers.h"
int main (void)
www.2cto.com
printf ("total expected cost: %d msec\n", total_msec);
sleep (1); // give 0mq time to deliver
zmq_close (sink);
zmq_close (sender);
zmq_ctx_destroy (context);
return 0;
} 圖 5 - 並行管道
這是工人程式。接收訊息,休眠指定的時間,然後表明自己完成任務:
taskwork: parallel task worker in c
[cpp]
//
// task worker
// connects pull socket to tcp://localhost:5557
// collects workloads from ventilator via that socket
// connects push socket to tcp://localhost:5558
// sends results to sink via that socket
//
#include "zhelpers.h"
int main (void)
zmq_close (receiver);
zmq_close (sender);
zmq_ctx_destroy (context);
return 0;
} 這是水槽程式。它收集這100個任務,然後計算整個處理消耗的時間,讓我們能夠證實如果有多個工人時他們真的是並行運轉的:
tasksink: parallel task sink in c
[cpp]
//
// task sink
// binds pull socket to tcp://localhost:5558
// collects results from workers via that socket
//
#include "zhelpers.h"
int main (void)
// calculate and report duration of batch
printf ("total elapsed time: %d msec\n",
(int) (s_clock () - start_time));
zmq_close (receiver);
zmq_ctx_destroy (context);
return 0;
} 批處理的平均消耗為5秒。當我們啟動1個、2個、4個工人時,我們從水槽取得的結果是這樣的:
[plain]
# 1 worker
total elapsed time: 5034 msec
# 2 workers
total elapsed time: 2421 msec
# 4 workers
total elapsed time: 1018 msec
讓我們更細緻的檢視這段**的某些方面:
工人們上游連線通風機,下游連線水槽。這意味著你可以任意新增工人。如果工人繫結到他們的端點,你會需要(a)更多的端點(b)每新增乙個工人都得修改通風機或水槽。我們說通風機和水槽是結構中的「穩定」部分,而工人們是「動態」部分。
我們不得不在批次的開始與所有工人們都起來執行兩者間做出同步。這是乙個ømq中特別常見的陷阱,也沒有簡單方案。「連線」方法需要一定時間。所以當一組工人連線到通風機,第乙個成功連線的工人會在瞬間得到訊息的全部負載,而其他人仍在連線。如果你總是不去同步批次的開始,系統完全不會並行運轉。試著移除等待看看。
通風機的推送(push)套接字均勻的分發任務到工人們(假定批次開始送出之前他們都已連線)。這叫做負載均衡,我們會再詳細看看。
水槽的拉取(pull)套接字均勻的收集工人的成果。這叫做公平佇列。
圖6 - 公平佇列
管道模式也表現出「遲鈍加入者」綜合症,導致了對推送套接字不能正確負載均衡的控訴。如果你使用推送和拉取,而且其中乙個工人比其他人得到更多的訊息,那是因為他的推送套接字比別人連線的更快,然後在其他人連線達成之前捕獲了一大堆訊息。如果你想要正確的負載均衡,你可能想要看看第3章 - 高階請求應答模式中的小節:負載均衡模式。
ZeroMQ指南 第1章 基礎 我們為何需要 MQ
現在你已經見識了 mq的實際應用,讓我們回到 為什麼 目前很多應用程式由跨越某種網路的元件組成,不是區域網就是網際網路。那麼多的程式設計師最終都在從事某種訊息傳遞。一些開發者使用訊息佇列產品,但大多是用tcp或udp來自己開發。這些協議不難使用,但是從a到b傳送少量位元組和任何可靠方式的訊息傳遞之間...
《Ansible權威指南》第1章
第一篇 part 1 基礎入門篇 第1章 ansible基礎入門 第2章 ansible基礎元素介紹 第3章 ansible ad hoc命令集 第4章 playbook快速入門 第5章 ansible playbook拓展 第1章 ansible基礎入門 從早期all in one 所有應用部署在...
1 第1章 Pandas基礎
1.5.2.5 練習二 現有乙份關於科比的投籃資料集,請解決如下問題 1.5.2.6 a 哪種action type和combined shot type的組合是最多的?df pd.read csv data kobe data.csv index col shot id df.head pd.se...