股票量化:赫茲量化系統(tǒng)OpenCL 中的多線程計算
利用 OpenCL 實現(xiàn)多線程計算
選擇了基本方法后,我們就能夠繼續(xù)實現(xiàn)了。 我們從創(chuàng)建內核(可執(zhí)行的OpenCL函數(shù))開始。 根據以上邏輯,我們將創(chuàng)建 4 個內核。
3.1. 前饋內核。
與之前文章中討論的方法類似,我們創(chuàng)建一個前饋推算內核?FeedForward?。
不要忘記內核是在每個線程中運行的函數(shù)。 調用內核時需設置此類線程的數(shù)量。 在內核內部的操作是特定循環(huán)內的嵌套操作;循環(huán)的迭代次數(shù)等于被調用線程的次數(shù)。如此,在前饋內核中,我們可以指定計算獨立神經元狀態(tài)的操作,并可從主程序調用內核時以指定神經元數(shù)量。
內核從參數(shù)中接收權重矩陣,輸入數(shù)據數(shù)組和輸出數(shù)據數(shù)組的引用,以及輸入數(shù)組的元素數(shù)量,和激活函數(shù)類型。 請注意,OpenCL 中的所有數(shù)組都是一維的。 因此,如果在 MQL5 中將二維數(shù)組用做權重系數(shù),則此處我們需要計算初始位置的位移,以便讀取第二個、及后續(xù)神經元的數(shù)據。
__kernel void FeedForward(__global double *matrix_w, ??????????????????????????????__global double *matrix_i, ??????????????????????????????__global double *matrix_o, ??????????????????????????????int inputs, int activation)
在內核的開頭,我們獲得線程的序列號,其可判定所計算神經元的序列號。 聲明私密(內部)變量,包括向量變量?inp?和?weight。 還要定義我們的神經元權重的位移。
??{ ?? int i=get_global_id(0); ?? double sum=0.0; ?? double4 inp, weight; ?? int shift=(inputs+1)*i;
接下來,組織一個循環(huán)來獲取輸入值與其權重的乘積的合計。 如上所述,我們用到 4 個元素?inp?和?weight?的向量來計算乘積合計。 然而,內核接收的所有數(shù)組并非都是 4 的倍數(shù),因此缺少的元素應替換為零值。 注意輸入數(shù)據向量中的一個 “1” - 它對應于貝葉斯偏差的權重。
?? for(int k=0; k<=inputs; k=k+4) ???? { ??????switch(inputs-k) ????????{ ???????? case 0: ?????????? inp=(double4)(1,0,0,0); ?????????? weight=(double4)(matrix_w[shift+k],0,0,0); ?????????? break; ???????? case 1: ?????????? inp=(double4)(matrix_i[k],1,0,0); ?????????? weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],0,0); ?????????? break; ???????? case 2: ?????????? inp=(double4)(matrix_i[k],matrix_i[k+1],1,0); ?????????? weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],0); ?????????? break; ???????? case 3: ?????????? inp=(double4)(matrix_i[k],matrix_i[k+1],matrix_i[k+2],1); ?????????? weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],matrix_w[shift+k+3]); ?????????? break; ???????? default: ?????????? inp=(double4)(matrix_i[k],matrix_i[k+1],matrix_i[k+2],matrix_i[k+3]); ?????????? weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],matrix_w[shift+k+3]); ?????????? break; ????????} ??????sum+=dot(inp,weight); ???? }