如何使用多线程计算非常大的数据集上的交集

时间:2015-10-22 13:24:05

标签: multithreading algorithm intersection

我有一个由400万套组成的文件。每组包含1到n个单词。文件大小 120 MB。

set1 = {w11, w12,...,w1i}
set2 = {w21, w22,...,w2j}
...
setm = {wm1, wm2,...,wmk}

我想计算所有集合之间的交集。

Set 1 ∩ {set1,...,setm}
Set 2 ∩ {set1,...,setm}
...
Set m ∩ {set1,...,setm}

每次操作都需要 1.2 秒。我做了以下几点:

  • 将400万套分成6块。每个包含 666666 的块

然后我做以下事情。在这里,我将创建36个线程,我将计算组块之间的交集。这太慢了,我把问题弄复了。

 vector<thread> threads;
 for(int i = 0; i< chunk.size();i++)
  {
    for(int j = 0; j < chunk.size();j++)
    {
       threads.push_back(thread(&Transform::call_intersection, this, ref(chunk[i]),ref(tmp[j]), chunk(results)));
    }
  }

for(auto &t : threads){ t.join(); }

您是否知道如何将问题划分为子问题,然后将所有这些问题加入到一起。在Linux中也有什么好办法吗?

样品

第一列表示集合的ID,其余列表示单词。

m.06fl3b|hadji|barbarella catton|haji catton|haji cat|haji
m.06flgy|estadio neza 86
m.06fm8g|emd gp39dc
m.0md41|pavees|barbarella catton
m.06fmg|round
m.01012g|hadji|fannin county windom town|windom
m.0101b|affray

实施例

m.06fl3b与m.01012g和m.0md41的交集。输出文件如下:

 m.06fl3b m.01012g m.0md41
 m.06flgy
 m.06fm8g
 m.0md41 m.06fl3b
 m.06fmg
 m.01012g  m.06fl3b
 m.0101b

1 个答案:

答案 0 :(得分:3)

设置交集是关联,因此适用于parallel folding(这是MapReduce的许多用例之一)。对于每对集合((1,2),(3,4),...),您可以计算每对的交集,并将结果放入一组新的集合中,这些集合的大小只有一半。重复,直到你只剩下一套。交叉操作的总数将等于组的数量减去一。

启动数百万个线程会让您的计算机陷入困境,但是,您可能希望使用线程池:创建一些接近CPU核心数量的线程可用,并创建一个任务列表,其中每个任务是两个要交叉的集合。每个线程重复检查任务列表并获取第一个可用任务(确保以线程安全的方式访问任务列表)。