C++ 如何在CUDA中比较多个向量(高效)

C++ 如何在CUDA中比较多个向量(高效),c++,optimization,vector,cuda,C++,Optimization,Vector,Cuda,简介 我正试图写一个程序来比较向量。我需要它将每个向量与其他向量进行比较,并返回一个向量c,其中c[I]=a[I]/b[I]。所以我需要一个向量C来表示集合中的每一对向量 代码——简化 __global__ void compare_vectors(*a, *b, *c) { c[ i ] = a[ i ] / b[ i ] } main() for(... all vectors...) compare_vectors <<<

简介

我正试图写一个程序来比较向量。我需要它将每个向量与其他向量进行比较,并返回一个向量c,其中c[I]=a[I]/b[I]。所以我需要一个向量C来表示集合中的每一对向量

代码——简化

__global__
void compare_vectors(*a, *b, *c)  
    { c[ i ]  =  a[ i ] / b[ i ]  }

main()

    for(... all vectors...)  
        compare_vectors <<< grid, block >>> (n, n+1, result)
\u全局__
无效比较向量(*a,*b,*c)
{c[i]=a[i]/b[i]}
main()
对于(…所有向量…)
比较向量>(n,n+1,结果)
问题

我的问题是这样做比在CPU上做慢。每次迭代for循环时,两个比较向量都被复制到设备内存,然后结果向量被复制回主机内存

我希望能够将每个向量与其他向量进行比较,但要高效地进行比较,然后立即将所有结果复制回来。我该如何构造它,以避免对cudaMemcpy的调用过多

信息
我是CUDA的新手,所以如果这是非常明显的,请原谅我

我已经阅读了许多教程,并四处搜索。但是所有其他的例子似乎都是比较两个很长的向量,而不是很多更小的向量。我已经做了很多的搜索和研究,但我找不到一个方法来做到这一点

我有大约2000个向量要比较。每个向量与其他向量进行比较。所以~2000^2比较。每个向量的长度为100-200个浮点数


谢谢@MartinBonner和@platinum95。把它画在网格上确实让事情变得更清楚。

你应该使用一个
cudaMemcpy
调用将所有向量从CPU复制到设备内存,然后在一个内核调用中计算所有的除法。在内核中,每个向量可以启动一个线程,然后该线程迭代所有其他向量并计算除法结果。如果您的GPU支持2000多个线程,那么您应该重新设计算法,使一个线程不迭代所有其他向量,而只迭代其中的
1/10
,然后其他9个线程迭代每个向量的
1/10

更新:您不需要将每一对从CPU传输到GPU。只需创建一个有足够空间容纳所有
N
向量的数组,每个
M
项都很长,然后在CPU上将
N*M
项逐个复制到此数组,然后调用
cudaMemcpy
在GPU上获取此数组。

tl;dr:不要在(离散的)GPU上这样做 正如@Talonmes所建议的,这个问题不适合使用GPU作为协处理器

你看,在英特尔平台上,GPU卡对主内存的访问方式与CPU不同;数据必须通过PCIe总线发送到it,PCIe总线的带宽要低得多(典型值:12 GB/sec,而CPU上的访问为30-40 GB/sec)。因此,虽然GPU执行计算的速度可能比CPU快,但只有当它们的“密度”(相对于您正在处理的数据量)足够高时,您才会看到好处

在您的例子中,您将为正在比较的每对向量传输一个向量。即使GPU在0时间内立即执行所有计算,由于需要将结果复制回来,它在这个问题上仍然比CPU慢


(还有,我真的怀疑你是否需要n*(n-1)/2个向量,这听起来很奇怪。)

Ahem<代码>2000²比较,这是很多,但比
2000少得多(大约10**13000)。您的问题太小,无法在GPU上盈利。不要浪费你的时间,它既不是阶乘也不是平方,它是一个组合问题,由2000年给出/(2!(2000-2)!)即1999000。另外,说计算200个小向量的1999000个浮点除法无利可图听上去是不真实的。@platinum95。不清楚OP是否要将a与b和b与a进行比较。我假设他是(并且忽略了一个事实,即a和a是没有意义的——这意味着它实际上是2000²-2000。)OP。要看到它大致是正方形,请画一个网格。用向量的名称标记每一行;用向量的名称标记每列。网格上的每个点都是一个向量与一个向量(可能是同一个)的比较。网格上有n²个点。谢谢。-我不明白你说的让线程在向量的十分之一上迭代是什么意思?你能详细说明一下吗@SergeRogatch@JohnMansell,而不是向量的
1/10
,而是要将当前向量与之进行比较的所有其他向量的
1/10
。当您说“您应该使用一个CUDAEMCPY调用将所有向量从CPU复制到设备内存”时。我怎么能一个电话就把他们全部转到cudaMemcpy?我应该把它们连接成一个长向量吗?另一个问题是,由于它们是历史股价,所以并非所有向量的长度都相同。因此,我无法按固定数量自动编制索引。我还必须传入每个向量的长度。(如果它们都连接到一个向量中)是的,可以将它们连接到一个长向量中。那么你确实也需要把长度传递给CUDA。谢谢你详细解释为什么GPU可能不是一个好的选择。我没有考虑过传输速度。实际上,我将在比较函数中做更多的数学运算,但我试图尽可能地简化这个问题。我试图把重点放在无法有效发送大量小向量的主要问题上。这会改变你的主张吗?我还是要看看我是否可以通过使用GPU来减少总的程序时间。现在,CPU在完整版本中运行200个向量大约需要10分钟@Einpoklume需要
O(N*N*M)
复杂性,其中
N
是向量的数量,
M
是向量的长度。如果
N=2000
M=200