为什么以相同的数量插入到集合中,基于不同的方法具有不同的运行时间?

why inserting into set with same amount has different runtimes based on different approaches?

本文关键字:方法 于不同 运行时间 集合 插入 为什么      更新时间:2023-10-16

我正在编写一个并行程序,它将组合生成为布尔向量形式。由于组合是使用线程生成的,因此我将在每个线程完成其工作时组合它们。

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^16m=2^24-2^16

在这里,"大O"里面的项变成了2^16 * log(2^24-2^16+2^16(,即2^16*24

情况 2: n=2^23m=2^23

在这里,相同的项是 2^23*24,是情况 1 的2^7

我的观点是,如果您"合并"两个具有相同元素总数的集合,则运行时可能在很大程度上取决于这些元素在它们之间的分布方式。

在第一种情况(10 个线程(中,集合大小的分布似乎更像情况 2(其中大多数具有相对较高的元素数量(。我们没有看到第二种情况(128 个线程(的完整数据,但设置的大小似乎分布得更不均匀,因为显示的元素很少。(请注意,它可能指示也可能不指示并行计算的负载平衡不佳。