【问题标题】:CUDA - check repeated values and add two valuesCUDA - 检查重复值并添加两个值
【发布时间】:2016-11-07 19:05:06
【问题描述】:

我有两组数组

a1 a2 a3 a4 a5 a6 a7 a8 <= name it as key1
b1 b2 b3 b4 b5 b6 b7 b8 <= val1
c1 c2 c3 c4 c5 c6 c7 c8

和

d1 d2 d3 d4 d5 d6 d7 d8 <= key2
e1 e2 e3 e4 e5 e6 e7 e8 <= val2
f1 f2 f3 f4 f5 f6 f7 f8

数组a1,...,an 和d1,...,dn 已排序并且可能会重复。即它们的值可能类似于1 1 2 3 4 6 7 7 7 ... 我想检查每个元组di,ei 是否等于ai,bi 中的任何一个。如果是(di==ai,bi==ei),那么我必须使用某些功能将fi 和ci 结合起来,例如添加并存储在fi中。

首先,是否可以使用 zip 迭代器和 thurst 库中的转换来有效地解决这个问题?

其次,我能想象的最简单的方法是计算每个键的出现次数 (ai) 做前缀求和并使用两者来获取每个键的开始和结束索引,然后对于每个 di 使用上面的计数来迭代这些索引并检查ei==di。并执行转换。

即如果我有

1 1 2 3 5 6 7
2 3 4 5 2 4 6
2 4 5 6 7 8 5

作为第一个数组,我计算了 1,2,3,4,5,6,7,...的出现次数:

2 1 1 0 1 1 1 <=name it as count

然后做前缀求和得到:

2 3 4 4 5 6 7  <= name it as cumsum

并用它来做:

for each element di,
    for i in (cumsum[di] -count[di]) to cumsum[di]:
        if ei==val1[i] then performAddition;

我担心的是,由于并非所有线程都是平等的,这会导致扭曲发散,并且我可能没有有效的性能。

【问题讨论】:

  • 它几乎是 this question 的复制品。拥有一个双键向量会稍微复杂一些,但如果我们能保证第二个子键向量在主键向量有重复的地方排序,那就不会复杂了。
  • 感谢您的评论。遗憾的是,无法保证订购。
  • 您可以强制排序(即重新排序重复项,因此子键是有序的)。否则,您将回到蛮力搜索(至少在重复键中),这将大大降低效率。

标签: c++ arrays cuda thrust


【解决方案1】:

您可以将数据视为两个键值表。Table1:(a,b) -&gt; c 和 Table2:(d,e)-&gt;f,其中 (a,b) 和 (d,e) 是键,c、f 是值。

那么你的问题就简化为

foreach key in Table2
  if key in Table1
    Table2[key] += Table1[key]

假设a 和b 的范围有限且为正数,例如unsigned char,将a 和b 组合成一个键的简单方法是

unsigned short key = (unsigned short)(a) * 256 + b;

如果key 的范围还没有像上例那样太大,您可以将Table1 创建为

int Table1[65536];

检查key 中的Table1 是否变为

if (Table1[key] != INVALID_VALUE)
  ....

有了所有这些限制,带推力的实现应该非常简单。


如果a 和b 具有更大的范围,如int,仍然可以使用类似的组合方法。

但如果key的范围过大,就得走Robert Crovella建议的方法了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    相关资源
    最近更新 更多