我們再來回顧下問題
在乙個記憶體檔案中找出所有以 windows換行符(\r\n
)結尾的行首指標,並儲存在陣列中,結果不要求有序
對於simt
的概念通常對應於gpu上的開發,我們選用目前最為流行的異構計算的庫cuda
,thrust
和openacc
來示例。
方法六 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.2
,nvcc 9.1
和pgc++ 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 遍歷這...