百度實習生招聘的一道大資料處理題目(下)

2021-06-13 12:14:49 字數 4321 閱讀 5614

圖4為排序階段cpu的使用率,可以看到只有乙個核達到了100%的利用率。下面為乙個多執行緒(執行緒的數量為核的數量)的排序版本,每個執行緒只對1g資料中的一部分進行快速排序,排序完成後再由另外乙個執行緒進行歸併,將結果寫入檔案。

多執行緒排序**如下:

/*multi_thread_sort.c*/

/* 

* author: chaos lee 

* date: 2012-06-30 

* description: load, merge , store data with single core, but sorting data with

all the cores provided by the smp 

*/ #include

#include

#include

#include

#include

#include

#include

#include

#include "../error.h"

#include "timer.h"

uint64_t * buffer = null; 

pthread_mutex_t counter_mutex = pthread_mutex_initializer; 

pthread_cond_t merge_start = pthread_cond_initializer; 

int cores_number; 

int counter; 

int uint64_compare(const void * ptr1,const void * ptr2) 

typedef struct segment_tag 

segment_t,*segment_p; 

void barrier() 

status = pthread_mutex_unlock(&counter_mutex); 

if(0 != status) 

err_abort("unlocking error.",status); 

} void * sort_thread_routin(void * args) 

void * merge_thread_routin(void * args) 

elapsed_seconds = get_elapsed_time(); 

fprintf(stdout,"sorting cost %d seconds.\n",elapsed_seconds); 

status = pthread_mutex_unlock(&counter_mutex); 

if(0 != status) 

err_abort("unlocking error.",status); 

dprintf(("begin to merge...\n")); 

finish_count = 0; 

segment_p segs = (segment_p) args; 

restart_timer(); 

while(finish_count } 

else } 

} segs[j].start++; 

if(segs[j].start >= segs[j].end) 

fwrite(&tmp,sizeof(uint64_t),1,fp_result); 

} elapsed_seconds = get_elapsed_time(); 

fprintf(stdout,"merging cost %d seconds.\n",elapsed_seconds); 

dprintf(("merging is over\n")); 

fclose(fp_result); 

pthread_exit((void *)0); 

} int main(int argc,char *argv) 

fp = fopen("data.dat","rb"); 

if(null == fp) 

start_timer(); 

fread(buffer,size,1,fp); 

elapsed_seconds = get_elapsed_time(); 

fprintf(stdout,"loading cost %d seconds\n",elapsed_seconds); 

segments = (segment_p)malloc(sizeof(segment_t)*cores_number); 

if(null == segments) 

for(i=0;i

sort_threads = (pthread_t *)malloc(sizeof(pthread_t) * cores_number); 

if(null == sort_threads) 

merge_thread = (pthread_t *)malloc(sizeof(pthread_t)); 

if(null == merge_thread) 

for(i=0;i

status = pthread_create(merge_thread,null,merge_thread_routin,(void *)segments); 

if(0 != status) 

err_abort("creating thread faulier.\n",status); 

for(i=0;i

status = pthread_join(*merge_thread,null); 

if(0 != status) 

err_abort("joining thread error.\n",status); 

free(buffer); 

fclose(fp); 

return 0; 

再編譯執行下,以下為測試結果:

[lichao@sg01 thread_power]$ gcc multi_thread_sort.c -o multi_thread_sort timer.o -lpthread 

[lichao@sg01 thread_power]$ ./multi_thread_sort 

loading cost 14 seconds 

sorting cost 22 seconds. 

merging cost 44 seconds. 

下圖5為多執行緒排序時cpu的利用率,可以看到cpu的四個核都已經達到100%的利用率,即:硬體沒有白投資:d。當然排序的時間效果也很好,幾乎達到了之前的4倍的加速比。另外可以看到檔案的載入速度和回寫速度也有所提高,這點也是讓我比較疑惑的。下面再次執行單執行緒排序版本。

圖5 排序階段cpu的利用率

[lichao@sg01 thread_power]$ ./single_thread_sort 

loading cost 17 seconds 

sorting cost 81 seconds 

writing results cost 12 seconds 

可以看到載入速度和回寫速度有了顯著的提公升,雖然排序時間還是沒有多大變化。

再次執行多執行緒排序版本試試:

[lichao@sg01 thread_power]$ ./multi_thread_sort 

loading cost 31 seconds 

sorting cost 22 seconds. 

merging cost 23 seconds. 

載入速度又延長了,排序速度幾乎不變,回寫速度也提高了不少。我想這主要是因為檔案系統本身提供了緩衝的作用,即上次用過的檔案可以放在交換區,便於迅速載入記憶體吧。這樣第二次使用的時候,由於這些檔案還存放在交換區中,所以以很高的速度傳入記憶體中。回寫的原理應該也一樣。對於1g的檔案回寫到記憶體,只用了23s,大致的回寫速度為50mb/s

假設檔案系統一直起作用,並能達到第二次實驗的效果,即分塊排序22s,歸併排序並回寫檔案系統23s,那麼計算和歸併回寫是能夠重合的。對於200g的檔案a來說,分塊排序的處理時間大致為:200*22s=~1.2h,就擴大為1小時15分鐘吧。這樣對檔案b來說也差不多為1小時15分鐘,一共需要2個半小時,接下來開始歸併比較了,假設檔案的緩衝系統能夠啟作用,即速度能達到50mb/s,這樣,對於2個200g的檔案都需要在記憶體中過一遍,大致時間應該為400*10^3/50 = 8000s,大致為2小時15分鐘,所以加上前面的2個半小時,對於2個200g的檔案尋找相同值共需要的時間為 5個小時左右,至少比300萬年好點。

ps: =~這個符號表示約等於

百度2011實習生招聘筆試題

一 簡答題 1 extern c 是什麼意思,作用是什麼?2 至少說出兩個設計模式,闡述內容及其適用情況,最好有偽 3 tcp ip中的time wait是什麼意思?在什麼情況下會出現,簡述其好處和壞處。二 演算法與程式設計 1 某系統每天要執行n個任務 n 1000 任務之間存在複雜的依賴關係,如...

百度2010實習生招聘筆試題

a卷 共三道大題 請先閱讀卷首的試卷說明,在a b卷選擇一套試卷作答,同時作答試卷無效 第一題 簡答題 1 簡要說明樹的深度優先 廣度優先遍歷演算法,及非遞迴實現的特點。2 在處理磁碟資料時,需要首先將其讀入記憶體才能進行處理。如果要讀取的資料已經在記憶體中,則可以直接訪問記憶體。通常來說記憶體是有...

2017百度實習生招聘程式設計題

一 度度熊想去商場買一頂帽子,商場裡有n頂帽子,有些帽子的 可能相同。度度熊想買一頂 第三便宜的帽子,問第三便宜的帽子 是多少?輸入描述 首先輸入乙個正整數n n 50 接下來輸入n個數表示每頂帽子的 均是正整數,且小於等於1000 輸出描述 如果存在第三便宜的帽子,請輸出這個 是多少,否則輸出 1...