我正在为多个持久对象指针列表中的多个CPU密集型进程添加多线程。创建了大约6000万个这些对象,并将其添加到主处理线程的主列表中。
所有的工作都发生在两个lambda仿函数中,一个用于处理数据(myMap),另一个用于收集结果(myReduce)。主要列表分为四个子列表,每个子列表大约1500万个,并发送到QtConcurrent::mappedReduced进行工作。这是一些示例代码:
//main thread
const int count = 60000000;
QList<MyObject*> list;
for(int i = 0; i < count; ++i) {
MyObject* obj = new MyObject;
obj.readFromFile(path);
list << obj;
}
QList<QList<MyObject*> > sublists;
for(int i = 0; i < count; i += count/4) {
sublists << list.mid(i, count/4);
}
QThreadPool::globalInstance()->setMaxThreadCount(1); //slowdown when set to 4??
Result results_total;
std::function<Result (const QList<MyObject*>&)>
myMap = [](const QList<MyObject*>& m) -> Result {
//do lots of work on individual MyObjects, querying and modifying them
};
auto myReduce = [&results_total](bool& /*noreturn*/, const Result& result) {
results_total.count += result.count;
results_total.othernumber += result.othernumber;
};
QFutureWatcher<void> fw;
fw.setFuture(QtConcurrent::mappedReduced<bool>(
sublists, myMap, myReduce,
QtConcurrent::OrderedReduce | QtConcurrent::SequentialReduce));
fw.waitForFinished();
这里是踢球者:当我setMaxThreadCount到4而不是1时,程序会减慢10%而不是加速200-400%。我使用完全相同的方法(将列表拆分为四分之一并通过QtConcurrent运行)在另一个程序上,并使用完全相同的数据集运行它,通过使用4个线程而不是1来进行大约4倍的速度提升。
谷歌搜索表明某处的myRun
仿函数必须有共享资源,但我无法找到除原始列表之外的处理线程之间共享的任何内容。主线程上存在的MyObject
。
所以问题是:如果我可以保证没有同步问题,那么MyObject是否在与处理线程不同的线程中创建的事实? This link表明它并不重要,但堆内存块似乎是两个线程共享的唯一内容。
我在带有i7处理器的Windows 7 Pro x64上运行Qt 4.8.6。