这种设置障碍的方法正确吗
Is this approach of barriers right?
我发现pthread_barrier_wait相当慢,所以在代码中的某个位置,我用我的barrier版本(my_barrier)替换了phread_brrier_wait,该版本使用原子变量。我发现它比pthread_barrier_wait快得多。使用这种方法有什么缺陷吗?这是正确的吗?此外,我不知道为什么它比pthread_barrier_wait更快?有线索吗?
编辑
-
我主要感兴趣的是有相同数量的线程作为核心的情况。
atomic<int> thread_count = 0; void my_barrier() { thread_count++; while( thread_count % NUM_OF_THREADS ) sched_yield(); }
您的屏障实现不起作用,至少在屏障将被多次使用的情况下不会起作用。考虑这种情况:
NUM_OF_THREADS-1
线程正在屏障处等待,正在旋转- 最后一根线到达并穿过障碍物
- 最后一个线程退出屏障,继续处理,完成下一个任务,然后重新进入屏障等待
- 直到现在,其他等待线程才得到调度,并且由于计数器再次增加,它们无法退出屏障。僵局
此外,使用动态分配的障碍来处理一个经常被忽视但令人讨厌的问题,那就是破坏/释放它们。您希望任何一个线程都能够在barrier wait返回后执行destroy/free,只要您知道没有人会再次尝试等待它,但这需要确保所有等待程序在任何等待程序醒之前都已完成对barrier对象中内存的触摸-这不是一个容易解决的问题。请参阅我过去关于实施障碍的问题。。。
如何在pthread_barrier_wait返回后立即消除障碍?
能否在Linux上实现正确的故障安全进程共享屏障?
除非你知道你有一个特殊情况,没有任何困难的问题适用,否则不要尝试为应用程序实现你自己的问题。
AFAICT这是正确的,看起来更快,但在激烈竞争的情况下,情况会更糟。最激烈的情况是当你有很多线程,远远超过CPU。
不过,有一种方法可以快速设置障碍,使用事件计数(通过谷歌查看)。
struct barrier {
atomic<int> count;
struct eventcount ec;
};
void my_barrier_wait(struct barrier *b)
{
eventcount_key_t key;
if (--b->count == 0) {
eventcount_broadcast(&b->ec);
return;
}
for (;;) {
key = eventcount_get(&b->ec);
if (!b->count)
return;
eventcount_wait(&b->ec);
}
}
这应该能更好地扩展。
尽管坦率地说,当你使用屏障时,我认为性能并不重要,它不应该是一个需要快速的操作,它看起来很像是过早的优化。
据我所见,您的屏障应该是正确的,只要您不经常使用屏障,或者您的线程数是2的幂。理论上,你的原子会在某个地方溢出(在典型的核心计数使用了数亿次之后,但仍然如此),所以你可能想添加一些功能来重置某个地方。
现在来谈谈为什么它更快:我不完全确定,但我认为pthread_barrier_wait
会让线程休眠,直到该唤醒为止。你的在这个条件下旋转,在每次迭代中都会屈服。然而,如果没有其他应用程序/线程需要处理时间,则线程可能会直接在yield
之后再次被调度,因此等待时间更短。至少在我的系统中,玩这种障碍似乎表明了这一点。
附带说明:由于您使用atomic<int>
,我假设您使用C++11。在这种情况下,使用std::this_thread::yield()
而不是sched_yield()
来消除对pthreads的依赖难道没有意义吗?
这个链接可能对您也很有帮助,它测量了各种屏障实现的性能(您的情况通常是lock xadd+while(i<NCPU)
,除了屈服)
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- Poco 库 PUT 方法未按预期工作,尽管主机、方法、内容类型设置正确
- 如何在Visual Studio 2017上将类方法设置为参数并将它们与lambda一起使用?
- 将类方法设置为 OpenSSL 回调
- 哪个是设置位的最佳方法以及为什么?
- 设置窗口几何图形特性的正确方法
- 有没有一种方法可以在不设置精度的情况下设置小数位数
- 将类方法设置为外部定义的函数
- 我如何调用我的3个数据成员中每个人的设置方法,然后显示由我的设置方法设置的值
- 使用其公共方法C 设置类的私人属性
- 位掩码:通过集合方法设置对象的不同状态
- 通过对象的指针数组分配内存,并使用方法设置它们的名称
- 设置为实例的静态值在从静态方法设置时有效,但不能从类内的静态方法设置
- 如何为静态模板方法设置别名
- 这种设置障碍的方法正确吗
- 在qt单元测试中是否可以用单独的方法设置测试数据?
- 如何使用类方法设置单个类数组元素
- 使用私有方法设置类变量
- gdb-python编程:如何编写代码,为C++类的每个方法设置断点
- 从派生类方法设置基对象