C ++随机迭代向量

时间:2015-10-13 08:04:13

标签: c++ multithreading algorithm vector random-access

我正在研究一个多线程程序,其中所有线程共享一些向量(只读)。每个线程的目标是遍历整个向量。尽管如此,所有线程都必须以不同的方式访问此向量。

由于向量是const并且在所有线程之间共享,我不能使用random_shuffle并且只是迭代它。目前我的解决方案是构建 一个crossref向量,它将包含共享向量的索引然后 洗牌这个载体,即

genre.name

尽管如此,这样做会揭示一些问题(1)它不是很有效,因为每个线程在访问共享向量之前都需要访问它的crossref向量,(2)由于所需的内存量,我有一些性能问题:共享向量非常大,我有很多线程和处理器。

有没有人有一些改进的想法,可以避免额外的内存?

5 个答案:

答案 0 :(得分:14)

您可以使用primitive root modulo n的代数概念。 基本上

  

如果n是正整数,则1和n - 1之间的整数是   coprime to n形成一组模数为n的原始类。这个小组   当且仅当n等于2,4,p ^ k或2p ^ k时才是循环的,其中p ^ k是   一个奇素数的幂

维基百科显示如何使用7作为生成器生成3以下的数字。

enter image description here

从这个陈述中你可以得到一个算法。

  1. 记下您的电话号码n
  2. 找到大于m
  3. 的下一个素数n
  4. 对于每个帖子,在F(0)2
  5. 之间选择一个唯一的随机数m
  6. 使用F(i+1) = (F(i) * F(0)) mod m计算下一个索引。如果该索引在[0, n]范围内,请访问该元素。如果没有走向下一个指数。
  7. m - 1次迭代后停止(或者当你获得1时,它是相同的。)
  8. 因为m是素数,所以2和m-1之间的每个数字都是m的互质数,因此是序列{1 ... m}的生成符。我们保证在前m - 1步骤中不会重复任何号码,并且会显示所有m - 1个号码。

    复杂性:

    • 第2步:完成一次,复杂程度相当于找到最多为n的素数,即sieve of Eratosthenes
    • 第3步:完成一次,你可以选择2,3,4,5等......这是O(thread count)
    • 的最低值
    • 第4步:O(m)时间,每个帖子的空格O(1)。你不需要存储F(i)。您只需知道第一个值和最后一个值。这与增量相同的属性

答案 1 :(得分:6)

如果我理解你想要以增量方式生成随机排列,你想要调用 n 次函数 f 这样它就可以生成从1到 n 的所有置换数,因此该函数具有恒定的内存。

如果你想在排列中获得均匀分布,我怀疑它是否存在,但你可能对这组排列的一个子集感到满意。

如果是这种情况,您可以通过使用 n 取一个 p 数字来生成排列,并计算[1]中的每个 i ,n]:i.p (mod n)。 例如,如果你有n = 5和p = 7,那么7%5 = 2,14%5 = 4,21%5 = 1,28%5 = 3,35%5 = 0。你可以结合几个这样的功能来获得满足你的东西......

答案 2 :(得分:2)

如果内存是您最大的问题,那么您必须将CPU周期换成内存空间。

E.g。 c ++&#39; s std::vector<bool>http://en.cppreference.com/w/cpp/container/vector_bool)是一个位数组,因此具有很高的内存效率。

每个帖子都可以拥有自己的vector<bool>,表明它是否访问了特定索引。然后,您必须使用CPU周期来随机选择尚未访问的索引,并在所有booltrue时终止。

答案 3 :(得分:2)

似乎this家伙以非常好的方式解决了你的问题。

这就是他在帖子第一行所说的内容:在这篇文章中,我将展示一种方法来制作一个迭代器,它将以随机顺序访问列表中的项目,只访问每个项目一次,告诉你何时访问了所有项目并完成了。它不会存储混洗列表,也不必跟踪已经访问过的项目。

他利用可变位长度块密码算法的强大功能来生成数组中的每个索引。

答案 4 :(得分:1)

这不是一个完整的答案,但它应该引导我们找到正确的解决方案。

你写过一些我们可以作为假设的东西:

  

(1)由于每个线程都需要访问它,因此效率不高   访问共享之前的crossref向量,

这不可能是真的。我们谈论的是一次间接查询。除非你的参考数据真的是一个整数的向量,否则这将代表你执行时间的无限小部分。如果您的参考数据是一个int的向量,那么只需制作它的N个副本并随机播放它们......

  

(2)由于内存量的原因,我有一些性能问题   需要:共享向量非常大,我有很多线程   和处理器。

有多大?你测量过了吗?向量中有多少个离散对象?每个人有多大?

多少个帖子?

多少个处理器?

你有多少记忆?

您是否分析过代码?您是否确定性能瓶颈在哪里?您是否考虑过更优雅的算法?