我有一个由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 秒。我做了以下几点:
然后我做以下事情。在这里,我将创建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
答案 0 :(得分:3)
设置交集是关联,因此适用于parallel folding(这是MapReduce的许多用例之一)。对于每对集合((1,2),(3,4),...),您可以计算每对的交集,并将结果放入一组新的集合中,这些集合的大小只有一半。重复,直到你只剩下一套。交叉操作的总数将等于组的数量减去一。
启动数百万个线程会让您的计算机陷入困境,但是,您可能希望使用线程池:创建一些接近CPU核心数量的线程可用,并创建一个任务列表,其中每个任务是两个要交叉的集合。每个线程重复检查任务列表并获取第一个可用任务(确保以线程安全的方式访问任务列表)。