为什么以相同的数量插入到集合中,基于不同的方法具有不同的运行时间?
why inserting into set with same amount has different runtimes based on different approaches?
我正在编写一个并行程序,它将组合生成为布尔向量形式。由于组合是使用线程生成的,因此我将在每个线程完成其工作时组合它们。
set<vector<bool>> Ci[T.size()];
//generate combinations in parallel and thread i add result in Ci[i]
start_time = omp_get_wtime();
set<vector<bool>> C;
for(int i=0;i<T.size();i++){
cout << "i=" << i << "t" << Ci[i].size() << endl;
C.insert(Ci[i].begin(),Ci[i].end());//here combine them into a single set
}
end_time = omp_get_wtime();
total_time = end_time - start_time;
cout << " Total time:" <<total_time << endl;
cout << C.size();
线程总数 T.size(( 会有所不同,但总组合(C 的大小(总是相同的。 例如
Enter threads:10
i=0 1
i=1 144
i=2 4320
i=3 47040
i=4 229320
i=5 550368
i=6 672672
i=7 411840
i=8 115830
i=9 11440
Total time:36.641s
C's size :2042975
Enter threads:128
i=0 9
i=1 45
i=2 165
...
i=120 10
i=121 11
i=122 12
i=123 13
i=124 14
i=125 15
i=126 16
i=127 18
Total time:6.432s
C's size :2042975
我不明白的是,在这两种情况下,我都在 C 中插入相同数量的组合。为什么花费的时间不一样?
我们没有看到所有必要的信息,但我怀疑问题是由集合大小的不均匀分布引起的。插入的复杂度是O(n log(m + n((,其中n是插入到(C
(的集合的大小,m是插入的集合的大小(Ci[i]
(。
现在,假设两个集合加起来有 2^24 个元素。
情况 1: n=2^16,m=2^24-2^16
在这里,"大O"里面的项变成了2^16 * log(2^24-2^16+2^16(,即2^16*24。
情况 2: n=2^23,m=2^23
在这里,相同的项是 2^23*24,是情况 1 的2^7倍。
我的观点是,如果您"合并"两个具有相同元素总数的集合,则运行时可能在很大程度上取决于这些元素在它们之间的分布方式。
在第一种情况(10 个线程(中,集合大小的分布似乎更像情况 2(其中大多数具有相对较高的元素数量(。我们没有看到第二种情况(128 个线程(的完整数据,但设置的大小似乎分布得更不均匀,因为显示的元素很少。(请注意,它可能指示也可能不指示并行计算的负载平衡不佳。
相关文章:
- 如何@ref同一方法的不同变体?
- 对象引用中的字段以不同的方法返回不同的值
- 如何泛化作用于不同类型的向量的函数?
- 由于相同的文件名/类名存在于不同的SO中而导致的SEG错误
- 使用相同方法但不同成员类型构建类的最佳方法
- 为什么以相同的数量插入到集合中,基于不同的方法具有不同的运行时间?
- 可能从单个方法返回不同类型的对象
- 不同向量启动作为类成员与方法中不同的矢量启动背后的原因是什么?
- 设计模式的工厂替代方法:具有不同构造函数的类
- 编写方法的不同方法
- 将相同的功能应用于不同大小的N数组的每个元素
- 模板参数适用于不同的STL容器
- 调用虚拟方法的不同方法
- 如何使用工厂方法创建不同的对象
- 编译器添加的优化导致"final"方法的不同行为
- C++-方法在不同的类上重载
- C++类方法返回不同的类型
- C++虚拟方法返回不同的派生类型
- 如何使此代码适用于不同计算机上的服务器和客户端
- 客户端 API 的make_unique、工厂方法或不同设计