我使用Differential Evolution来模拟多元回归模型,甚至还使用了多处理选项来帮助减少运行时间。然而,对于7个自变量(每个自变量有10个值)和21个100+元素矩阵的矩阵运算,在24个内核上运行需要花费一些时间。我在PyOpenCL的多处理方面没有太多经验,因此,我想问一下,是否值得尝试将这两种方法集成到GPU上。我附上了包含3个变量和3个值的代码片段,以供参考:
import scipy.optimize as op
import numpy as np
def func(vars, *args):
res = []
x = []
for i in args[1:]:
if len(res) + 1 > len(args)//2:
x.append(i)
continue
res.append(np.array(i).T)
f1 = 0
for i in range(len(x[0])):
for j in range(len(x[1])):
diff = (vars[0]*x[0][i] + vars[1])*(vars[2]*x[1][j]*x[1][j] + vars[3]*x[1][j] + vars[4])*(vars[5]*50*50 + vars[6]*50 + vars[7])
f1 = f1 + abs(res[0][i][j] - diff) # ID-Pitch
f2 = 0
for i in range(len(x[0])):
for j in range(len(x[2])):
diff = (vars[0]*x[0][i] + vars[1])*(vars[5]*x[2][j]*x[2][j] + vars[6]*x[2][j] + vars[7])*(vars[2]*10*10 + vars[3]*10 + vars[4])
f2 = f2 + abs(res[1][i][j] - diff) # ID-Depth
f3 = 0
for i in range(len(x[1])):
for j in range(len(x[2])):
diff = (vars[2]*x[1][i]*x[1][i] + vars[3]*x[1][i] + vars[4])*(vars[5]*x[2][j]*x[2][j] + vars[6]*x[2][j] + vars[7])*(vars[0]*3.860424005 + vars[1])
f3 = f3 + abs(res[2][i][j] - diff) # Pitch-Depth
return f1 + f2 + f3
def main():
res1 = [[134.3213274,104.8030828,75.28483813],[151.3351445,118.07797,84.82079556],[135.8343927,105.9836392,76.1328857]]
res2 = [[131.0645086,109.1574174,91.1952225],[54.74920444,30.31300092,17.36537062],[51.8931954,26.45139822,17.28693162]]
res3 = [[131.0645086,141.2210331,133.3192429],[54.74920444,61.75898314,56.52756593],[51.8931954,52.8191817,52.66531712]]
x1 = np.array([3.860424005,7.72084801,11.58127201])
x2 = np.array([10,20,30])
x3 = np.array([50,300,500])
interval = (-20,20)
bds = [interval,interval,interval,interval,interval,interval,interval,interval]
res = op.differential_evolution(func, bounds=bds, workers=-1, maxiter=100000, tol=0.01, popsize=15, args=([1,2,2], res1, res2, res3, x1, x2, x3))
print(res)
if __name__ == '__main__':
main()
1条答案
按热度按时间vfwfrxfs1#
首先,是的,这是可能的,
func
可以是一个函数,该函数将数据发送到GPU,然后等待计算完成,然后将数据传输回RAM并返回到scipy。将计算从CPU端更改为GPU端并不总是有益的,因为从GPU来回传输数据需要时间,因此,对于中等的笔记本电脑GPU(例如),您根本不会获得任何加速,您的代码可能会更慢。减少GPU和RAM之间的数据传输可以使GPU比普通CPU快2-4倍,但您的代码需要数据传输,因此这是不可能的。
对于具有高带宽的强大GPU(如RTX 2070或RTX 3070或APU),您可以期望更快的计算,因此GPU上的计算速度将比CPU快几倍,即使是数据传输,但这取决于CPU和GPU代码的代码实现。
最后,您的代码可以在不使用GPU的情况下加速,这可能是您在进行GPU计算之前应该做的第一件事,主要是通过使用代码编译器(如cython和numba),这些编译器可以在不进行重大修改的情况下将代码速度提高近100倍,但您应该将代码转换为仅使用固定大小的预分配numpy数组,而不是列表,因为代码会快得多,您甚至可以禁用GIL并使代码多线程化,而且其中有很好的多线程循环实现。