一道簡單面試題引出的優化方法討論

2021-08-15 14:46:29 字數 3127 閱讀 5058

我們再來回顧下問題

在乙個記憶體檔案中找出所有以 windows換行符(\r\n)結尾的行首指標,並儲存在陣列中,結果不要求有序

對於simt的概念通常對應於gpu上的開發,我們選用目前最為流行的異構計算的庫cudathrustopenacc來示例。

方法六 simt

將樸素演算法移植到cuda上

static

const size_t block_size = 128;

__global__ void foo(const

char *array, size_t *tokens, int *token_index)

else

__syncthreads();

if (s_array[threadidx.x] == '\r' && s_array[threadidx.x + 1] == '\n')

}void tokenize(const

char *buffer, size_t buffer_size, size_t *tokens, size_t token_size)

方法七 simt

將方法二移植到cuda上

static

const size_t block_size = 128;

__global__ void foo(const

char *array, size_t *tokens, int *token_index)

if (s_array[block_size * 2 - 1] == '\r' && s_array[block_size * 2] == '\n')

}else

}else

if (s_array[s_offset] == '\n')}}

}void tokenize(const

char *buffer, size_t buffer_size, size_t *tokens, size_t token_size)

方法八 simt

對方法六進一步優化,增加單個執行緒的計算量,減少執行緒數目

static

const size_t block_size = 128;

static

const size_t segment_size = sizeof(int);

__global__ void foo(const

char *array, size_t *tokens, int *token_index)

}}void tokenize(const

char *buffer, size_t buffer_size, size_t *tokens, size_t token_size)

方法九 simt

使用cuda自帶的並行演算法庫thrust來實現

static thrust:

:host_vector h_input;

struct transform

else

}};struct predicate

};void tokenize(const char *buffer, size_t buffer_size, size_t *tokens, size_t token_size)

方法十 simt

使用openacc程式設計介面移植樸素演算法

void tokenize(const

char *restrict buffer, size_t buffer_size, size_t *restrict tokens, size_t token_size)

tokens[index] = i + 2;}}

}

方法十一 simt

使用openacc程式設計介面移植方法二

void tokenize(const char *buffer, size_t buffer_size, size_t *tokens, size_t token_size)

tokens[index] = i + 2;}}

else

if (buffer[i] == '\n')

tokens[index] = i + 1;}}

}if (buffer_size > 1 && (buffer_size & 0x01) == 0x01)

}

對於以上六種方法,我們看一下實際運**況

cuda的程式使用了特殊的語法,需要使用其自帶的nvcc編譯器,openacc的程式使用了pgc++編譯器

資料:構造1g長的隨機檔案,其中\r\n出現的概率分別是1/256,總行數16432

方法

用時(ms)

kernel用時(ms)

方法六302

35方法七

28823

方法八281

13方法九

344-

方法十218

-方法十一

200-

注意到tokenize方法的用時並不低,其中主要的耗時**於cpu記憶體與gpu記憶體之間資料的拷貝上,因為我們的例子實在太過簡單,所以記憶體拷貝消耗的時間已經高於計算本身的時間。

為此,我在cuda程式中特地單獨測量了kernel的耗時。

測試機器 cpu:e5-2690 v3 @ 2.60ghz,6核6執行緒,gpu:nvidia tesla k80

編譯器gcc 7.2nvcc 9.1pgc++ 17.10編譯選項-o2

一道簡單的面試題

設初始區間為seq0 0.0,1,0 產生乙個隨機數插入原來區間形成新區間seq1 假設產生0.7,則seq1 0.0,0.7,1.0 對seq1中的區間的子相鄰區間 如 0.0,0.7 和 0.7,1.0 取最大值,再次在此區間產生隨機數並插入.如此不斷重複。演算法很簡單,維護乙個鍊錶即可。每產生...

一道面試題

一道面試題 射擊運動員10發打中90環有多少種可能,請編寫程式計算出來,並列印出結果,0環和10環均有效。打中90環就是沒打中10環,所以打中90環跟打中10環的可能性是一樣的。然後開始遞迴狂打槍,一到10就記錄 if params i 10 在迴圈的控制中已經排除了大於10的可能性 i 10 pa...

一道面試題

前些時候在找工作,就在準備結束此次找工作歷程的時候,去了一家公司面試,去了之後技術經理直接帶到一台電腦旁,給了一張紙條,上面是這樣的題目 用c或c 來實現 1 建立一棵樹,該樹的深度是隨機的,每個節點的位元組點數是隨機的。2 給每個節點分配一段隨機大小的記憶體空間,給每個節點賦乙個隨機數。3 遍歷這...