從串行到并行,從并行到分布式

問題:串行(Sequential)、并行(parallel)、并發(Concurrent)和分布式(distributed)的區別是什么?

1. 概念

假設有AB兩個任務,則串行、并行、并發的區別如圖1所示。

串行

A和B兩個任務運行在一個CPU線程上,在A任務執行完之前不可以執行B。即,在整個程序的運行過程中,僅存在一個運行上下文,即一個調用棧一個堆。程序會按順序執行每個指令。

并行

并行性指兩個或兩個以上事件或活動在同一時刻發生。在多道程序環境下,并行性使多個程序同一時刻可在不同CPU上同時執行。比如,A和B兩個任務可以同時運行在不同的CPU線程上,效率較高,但受限于CPU線程數,如果任務數量超過了CPU線程數,那么每個線程上的任務仍然是順序執行的。

并發

并發指多個線程在宏觀(相對于較長的時間區間而言)上表現為同時執行,而實際上是輪流穿插著執行,并發的實質是一個物理CPU在若干道程序之間多路復用,其目的是提高有限物理資源的運行效率。 并發與并行串行并不是互斥的概念,如果是在一個CPU線程上啟用并發,那么自然就還是串行的,而如果在多個線程上啟用并發,那么程序的執行就可以是既并發又并行的。


圖1 串行、并行、并發的區別

而分布式和并行的區別如下:

分布式

分布式在并行處理的基礎上,強調任務正在執行的物理設備,如處理器、內存等等硬件,在物理上是分開的。而并行計算是指在一臺計算機上的計算,在物理上不分開。

2. 例子

假設有A,B兩個任務,任務A需要計算1-100000之間所有質數的和,任務B需要計算100001-200000之間所有質數的和。

則采用串行的方法設計的程序如下:
public class Main {
    //判斷是否為質數
    private static boolean isPrime(int n) {
        if(n < 2) return false;
        if(n == 2) return true;
        if(n%2==0) return false;
        for(int i = 3; i < n; i += 2)
            if(n%i == 0) return false;
        return true;
    }
    //串行計算
private static void serial() {
        long time1 = System.currentTimeMillis(), time2,time3;
        long count = 0;
        for(int i=1;i<=100000;++i){
            if(isPrime(i)) count+=i;
        }
        time2=System.currentTimeMillis();
        System.out.println("1-100000之間質數和為"+count+" 耗時:"+(time2- time1) + "毫秒");
        count = 0;
        for(int i=100001;i<=200000;++i){
            if(isPrime(i))
                count+=i;
        }
        time3 = System.currentTimeMillis();
        System.out.println("100001-200000之間質數和為"+count+" 耗時:"+(time3 - time2) + "毫秒");
        System.out.println("總耗時:"+ (time3 - time1) + "毫秒");
    }
    //主函數
    public static void main(String[] args) {
        serial();
    }
}

在串行計算的程序中,只有一個CPU線程,且該線程按順序執行AB兩個任務。程序運行結果如下:
串行計算的運行結果
采用并發的方法設計的程序如下:
public class Main{
    private static boolean isPrime(int n) {
        if(n < 2) return false;
        if(n == 2) return true;
        if(n%2==0) return false;
        for(int i = 3; i < n; i += 2)
            if(n%i == 0) return false;
        return true;
    }
    public static void main(String[] args) {
        serialConcurrency();
    }
    private static void serialConcurrency() {
        long time = System.currentTimeMillis();
        //任務切換標識,1代表A任務,2代表B任務
        int task = 1;
        //計數器
        long count1 = 0, count2 = 0;
        int i=1,j=100001;
        while (true)
        {
            if(task == 1 && i++<=100000) {
                if(isPrime(i)) count1+=i;
                task = 2;
            }
            else if(task == 2 && j++<=200000) {
                if(isPrime(j)) count2+=j;
                task = 1;
            }
            else{
                break;
            }
        }
        System.out.println("1-100000之間質數和為"+count1);
        System.out.println("100001-200000之間質數和為"+count2);
        System.out.println("總耗時:"+(System.currentTimeMillis() - time) + "毫秒");
    }
}

在并發計算的程序中,同樣只有一個CPU線程,但是該線程會在AB兩個任務之間進行切換,可以發現,并發計算的總耗時反而大于串行計算,這是因為CPU在任務切換過程中需要消耗一定時間。程序運行結果如下:
并發計算的運行結果
采用并行的方法設計的程序如下:
public class Main {
    public static boolean isPrime(int n) {
        if(n < 2) return false;
        if(n == 2) return true;
        if(n%2==0) return false;
        for(int i = 3; i < n; i += 2)
            if(n%i == 0) return false;
        return true;
    }
    public static void main(String[] args) throws InterruptedException {
        long time1 = System.currentTimeMillis(),time2;
        Task task1 = new Task(1,100000);
        Task task2 = new Task(100001,200000);
        Thread thread1 = new Thread(task1);
        Thread thread2 = new Thread(task2);
        thread1.start();
        thread2.start();
        while (thread1.isAlive() || thread2.isAlive()){
            Thread.sleep(1);
        }
        time2 = System.currentTimeMillis();
        System.out.println("總耗時:"+(time2 - time1)+"毫秒");
    }
}
class Task implements Runnable{
    private int start;
    private int end;
    Task(int start, int end) {
        this.start = start;
        this.end = end;
    }
    public void run() {
        long time = System.currentTimeMillis();
        long count = 0;
        for(int i=start;i<=end;++i){
            if(Main.isPrime(i)) count+=i;
        }
        System.out.println(String.format("%d-%d之間質數和為%d,耗時:%d毫秒",start,end,count,(System.currentTimeMillis()- time)));
    }
}

在并行計算的程序中,AB任務各占用一個CPU線程,AB任務同時執行,總共耗費的時間約等于AB任務的最長耗時,程序運行結果如下:
并行計算的運行結果
模式 CPU線程數 總耗時
串行 1 2736毫秒
并發 1 2933毫秒
并行 2 2277毫秒

3.總結

由上表可知并行的總耗時是最小的,效率最高(如果AB兩個任務耗時更接近,則并行計算的效率將更高)。但由于并行計算受限于CPU線程數,當計算量超出單臺計算機的計算能力時,人們就開始考慮使用多臺計算機同時處理一個任務,分布式計算應用而生。分布式計算將任務分解成許多小的部分,分配給多臺計算機進行處理,從而整體上節約了計算時間。Hadoop的MapReduce就是一種分布式計算框架,我們之后會對MapReduce進行詳細的探討。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容