2012-06-12 58 views
0

我有一百万列x一百万行的矩阵。用gpgpu做大量矢量计算的最佳方法是什么?

我algoritm需要做的:

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; 
}} 

我的问题:什么是分配内存和初始化内存的正确方法这个问题:

- 我应该为整个矩阵分配内存,用全矩阵初始化它, d然后运行算法?
- 或者我应该分配一个向量列表的内存,然后遍历这个列表?
- 否则??

我担心的是我想尽量减少传输时间到GPU。我试图通过修改JCublas hello world example以在2个矢量上进行sgemm操作来尝试这种计算,但是当在大量矢量上进行sgemm操作时,结果是传输时间删除了gpu加速的好处。

Thx! PS:实现可以在任何Java库中

+0

这是一个稀疏或密集的矩阵?一个100万×100万的32位整数或浮点值的密集矩阵需要4000 Gb的内存。这不仅不适合任何GPU内存,也不适合任何不需要专用数据中心的主机系统的内存。你打算做什么样的机器? – talonmies

+0

@talonmies我使用一个包含250,000个双值稀疏向量的数组。任何矢量的长度是1,100,000。 (http://code.google.com/p/matrix-toolkits-java/source/browse/trunk/src/no/uib/cipr/matrix/sparse/SparseVector.java?r=46)。向量*非常稀疏(平均10个值被填充)。目前,我可以使用i7-2860,16Gb笔记本电脑上的多线程来运行它,但需要几个小时。 – seinecle

回答

0

这听起来像是你正在执行一次一个的限制。 CPU-> GPU拷贝,等待,计算,GPU-> CPU拷贝,等待。大多数人没有意识到内存复制可能导致的隐含等待。

你能管理你的操作吗?换句话说,你的循环是否包含以下内容?

  • CPU-> GPU副本
  • GPU计算
  • GPU-> CPU副本

流水线这一点,你会使用(例如)4个单独的(按顺序)命令队列,问题在每个队列上对GPU进行非阻塞传输,在每个队列上发出内核执行,并按照该顺序在每个队列上发出GPU-> CPU副本。您必须保证两个缓冲区保持有效,直到等待(稍后介绍)。这将允许GPU在随后的内存传输发生时开始计算。

此外,从来没有使用阻塞内存传输,总是使用非阻塞。每传输一次(8次),就为GPU-> CPU拷贝获取一个事件对象,但如果这不是第一次迭代,则等待最后一个事件对象。这将节制您的队列并允许您重新使用缓冲区,但重叠操作会使传输和计算重叠。我们正在等待8次迭代之前的转移,所以我们不排空队列。管理队列深度非常重要,过多的工作项导致GUI和工作项匮乏。

相关问题