我有一个100万列×100万行的矩阵。
我的算法需要做:
Matrix m = Matrix(rows,cols)
for (colB: cols){
vector currColA = m.getcolumn(colA)
for (colB: cols){
vector currColB = m.getcolumn(colB)
result = currColA.dotProduct(colB)
return result;
}}
或者您也可以说:
Vectors [] v = Vectors[]
for (i: v.length){
vector v1 = v[i]
for (i: v.length){
vector v2 = v[i]
result = v1.dotProduct(v2)
return result;
}}
我的问题:为这个问题分配内存和初始化内存的正确方法是什么:
- 我应该为完整矩阵分配内存,用完整矩阵初始化它,然后运行算法?
- 或者我应该为矢量列表分配内存,然后遍历此列表?
- 或者其他??
我担心的是,我希望尽可能减少到gpu的传输时间。我已经通过修改JCublas hello world example对2个向量的sgemm操作尝试了这种计算,但是当我在大量向量上执行时,最终传输时间删除了gpu加速的好处。
THX! PS:实现可以在任何Java库中
答案 0 :(得分:0)
听起来你正在强制执行一次一个限制。 CPU-> GPU复制,等待,计算,GPU-> CPU复制,等待。大多数人都没有意识到内存副本可能导致的隐式等待。
您可以管理您的运营吗?换句话说,你的循环是否包含以下内容?
要对此进行管道传输,您将使用(例如)4个单独(按顺序)命令队列,在每个队列上向GPU发出非阻塞传输,在每个队列上发出内核执行,并发出GPU->按顺序在每个队列上复制CPU。您必须保证两个缓冲区在等待之前保持有效(稍后描述)。这将允许GPU在后续的内存传输过程中开始计算。
此外,永远不要使用阻止内存传输,始终使用非阻塞。每隔这么多(8?)次传输,获取GPU-> CPU复制的事件对象,但如果不是第一次迭代,则先等待最后一个事件对象。这将限制您的队列并允许您重用缓冲区,但重叠操作会使传输和计算重叠。我们正在等待8次迭代前的转移,所以我们没有排空队列。管理队列深度很重要,过多的工作项会导致滞后的GUI和工作项目的饥饿。