我有一些专有代码,基本上执行一个三重for循环。我决定通过将其中一个循环移动到std::execution::par_unseq
策略的std::for_each
结构中来加速。
这段代码更新了一些共享的std::vector,它现在被一个互斥锁保护着。这段代码没有静态局部变量。
std::vector<OutputType>
Detector::Detect(
const std::vector<Points>& path,
const std::vector<Object>& objects) const {
std::vector<OutputType> hits;
std::mutex mtx;
std::for_each (std::execution::par_unseq,
objects.cbegin(),
objects.cend(),
[&](auto const& obj){
std::set<ObjectId> already_hit;
for (size_t i = 0; i < path.size(); ++i) {
if (already_hit.contains(obj.id_)) {
continue;
}
for (size_t j = 0; j < obj.convex_hull.size(); ++j) {
auto pt = CalcThings(path[i], obj.convex_hull[j]),;
if (Condition(pt, path[i])) {
{
std::lock_guard<std::mutex> lock(mtx);
hits.emplace_back(OutputType(path[i], obj.id_));
}
already_hit.insert(obj.id_);
break;
}
}
}
});
return hits;
}
字符串
我有一个驱动程序代码,在检查下运行代码并测量执行时间。为了消除疑虑,tic和toc将一些静态初始化带入故事,我在for之前调用了这对代码。
for (int i = 0; i < 100; ++i) {
FrameContent content = ReadNextFrame();
if (content.valid) {
Detector detector(args);
{
tic(0, "detector_name", content.path.size(),
content.objects.size());
detector.Detect(content.path, content.objects);
toc();
}
}
}
型
然而,保存到文件中的输出看起来很奇怪,因为第一次运行需要相当多的时间:
| 检测器|NS|患者数量|# objs|
| --|--|--|--|
| 让静力学浪费时间| 190 | 0 | 0 |
| 检测器名称| 4400605 | 655 | 41 |
| 检测器名称| 538334 | 609 | 41 |
| 检测器名称| 494972 | 645 | 41 |
| 检测器名称| 435749 | 643 | 44 |
| 检测器名称| 408687 | 608 | 44 |
| 检测器名称| 398247 | 637 | 41 |
| 检测器名称| 387577 | 644 | 43 |
| 检测器名称| 382989 | 626 | 45 |
| 检测器名称| 396695 | 655 | 44 |
| 检测器名称| 368802 | 604 | 41 |
| 检测器名称| 379612 | 606 | 41 |
| 检测器名称| 377248 | 602 | 43 |
| 检测器名称| 382789 | 604 | 43 |
| 检测器名称| 418576 | 679 | 43 |
| 检测器名称| 392887 | 609 | 47 |
| 检测器名称| 490854 | 608 | 49 |
| 检测器名称| 413126 | 605 | 48 |
| 检测器名称| 456449 | 678 | 51 |
| 检测器名称| 466518 | 664 | 46 |
| 检测器名称| 428225 | 643 | 43 |
| 检测器名称| 378280 | 607 | 46 |
| 检测器名称| 392197 | 624 | 50 |
| 检测器名称| 401313 | 641 | 43 |
| 检测器名称| 448904 | 681 | 45 |
| 检测器名称| 421893 | 643 | 45 |
| 检测器名称| 446910 | 682 | 42 |
| 检测器名称| 491936 | 678 | 46 |
让我很困扰的是第一帧的运行时间要高出一个数量级,这与其中的数据量无关。
为什么会发生这种情况?是不是虚拟表的缓存(Detector是一个实现了override
接口的类)?
1条答案
按热度按时间gj3fmq9x1#
感谢@HolyBlackCat,问题似乎是ThreadPool初始化。
我添加了一个简单的:
字符串
结果如下(注意,下面的条目是针对向量中的100'000和1' 000 '000个元素)
| 检测器|NS|患者数量|# objs|
| --|--|--|--|
| detector_name(vec size 10'000)| 1361699 | 655 | 41 |
| detector_name(vec大小100'000)| 776356 | 655 | 41 |
| detector_name(vec size 1'000'000)| 699039 | 655 | 41 |
我想,第一次尝试确实创建了一些线程,但需要更多,因此可以实现额外的时间削减。