【问题标题】:best way to do large number of vector computations with gpgpu?使用 gpgpu 进行大量矢量计算的最佳方法?
【发布时间】:2012-06-15 13:19:06
【问题描述】:

我有一个 100 万列 x 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 加速的好处。

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

【问题讨论】:

  • 这是稀疏矩阵还是稠密矩阵? 32 位整数或浮点值的 100 万 x 100 万密集矩阵需要 4000 Gb 内存。这不仅不适合任何 GPU 内存,也不适合任何不需要专用数据中心的主机系统的内存。您打算在哪种机器上进行此操作?
  • @talonmies 我使用了一个包含 250,000 个双值稀疏向量的数组。任何向量的长度都是 1,100,000。 (code.google.com/p/matrix-toolkits-java/source/browse/trunk/src/… 向量 very 稀疏(平均填充 10 个值)。目前我可以在 i7-2860、16Gb 的笔记本电脑上使用多线程运行它,但需要几个小时。

标签: java opencl gpgpu jocl jcuda


【解决方案1】:

听起来您正在执行一次 1 次限制。 CPU->GPU 复制,等待,计算,GPU->CPU 复制,等待。大多数人没有意识到内存复制可能导致的隐式等待。

您可以流水线化您的运营吗?换句话说,您的循环是否包含以下内容?

  • CPU->GPU 复制
  • GPU 计算
  • GPU->CPU 拷贝

要流水线化,您将使用(例如)4 个单独的(按顺序)命令队列,在每个队列上向 GPU 发出非阻塞传输,在每个队列上发出内核执行,然后发出 GPU->CPU按顺序复制每个队列。您必须保证两个缓冲区在等待之前都保持有效(稍后描述)。这将允许 GPU 在进行后续内存传输时开始计算。

另外,永远不要使用阻塞内存传输,总是使用非阻塞。每隔这么多(8 个?)传输,为 GPU->CPU 副本获取一个事件对象,但如果这不是第一次迭代,则首先等待最后一个事件对象。这将限制您的队列并允许您重用缓冲区,但重叠操作会使传输和计算重叠。我们在 8 次迭代前等待传输,所以我们不会排空队列。管理队列深度很重要,过多的工作项会导致 GUI 滞后和工作项饥饿。

【讨论】:

    猜你喜欢
    • 2017-05-11
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2016-08-13
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多