STL 中不必要的锁定? (Visual C++ Express)

发布于 2024-09-28 22:37:41 字数 679 浏览 0 评论 0原文

我正在尝试构建一个可以扩展到多个核心的俄罗斯方块人工智能算法。

在我的测试中,结果表明使用多个线程比使用单个线程慢。

经过一些研究,我发现我的线程大部分时间都在等待_Lockit _Lock(_LOCK_DEBUG)。这是屏幕截图

正如您所看到的,锁应用于局部变量,无论如何它都不需要任何锁定!

我的问题是:

  • 为什么STL要锁定这个向量?
  • 我怎样才能让我的程序更快? (使用数组?)

更新

我通过在 Visual Studio 项目中设置这些命令行选项消除了锁定:

/D "_HAS_ITERATOR_DEBUGGING=0" /D "_SECURE_SCL=0"

将其应用于解决方案文件中的所有项目非常重要,否则在运行时会发生错误(迭代器冲突等)。

我更改的第二件事是将 std::vector 更改为 std::vector。我不知道 std::vector 这么慢。

I'm trying to build a Tetris AI algorithm that can scale over multiple cores.

In my tests it turns out that using multiple threads is slower than using a single thread.

After some research I found that my threads spend most of their time waiting for _Lockit _Lock(_LOCK_DEBUG). Here's a screenshot.

As you can see, the lock is applied on a local variable, which shouldn't require any locking anyway!

My questions are:

  • Why does STL lock this vector?
  • How can I make my program faster? (Use arrays?)

Update

I eliminated the lock by setting these command line options in my Visual Studio projects:

/D "_HAS_ITERATOR_DEBUGGING=0" /D "_SECURE_SCL=0"

It's important to apply this to all projects in the solution file or errors will occur at runtime (conflicting iterators etc).

The second thing I changed was changing std::vector<bool> into std::vector<char>. I wasn't aware that std::vector<bool> was so slow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷月断魂刀 2024-10-05 22:37:41

如果您将时间花在 LOCK_DEBUG 上,那么您正在使用调试迭代器。这些迭代器都会跟踪它们的位置和父容器,并为您检测几种未定义行为的情况。然而,它们确实会带来运行时成本。

在发布模式下编译,看看这是否仍然是瓶颈。可能还需要一个额外的开关或#define 来关闭它们——这不是积极的。

任何其他锁定实际上都是正确操作所必需的——当您从向量中读取数据时,必须确保没有人同时写入该向量(至少要获得大多数 STL 所期望的线程安全性)实现——即不同的读者是安全的,即使多个作者不安全)。这需要锁定来维护。

还要考虑不使用 vector(使用 dequevectorvector)。 相反),因为它通常需要更多的线程开销,因为它将伪布尔值存储在各个位中。这让它可以在更小的空间中容纳更多的内容,但不幸的是,这意味着对容器的读取和写入不再是原子的,这可能需要更多的锁定。

If you're spending time in LOCK_DEBUG, then you are using the debugging iterators. These iterators all track their positions and parent containers, and detect several cases of undefined behavior for you. They do, however, impose a runtime cost.

Compile in release mode and see if that's still a bottleneck. There might be an additional switch or #define required to turn them off too -- not positive.

Any other locking is going to actually be required for correct operation -- when you're reading from the vector, you must ensure nobody is writing to that vector at the same time (at least to get the kind of thread safety expected of most STL implementations -- namely that different readers are safe, even though multiple writers are not). That requires locking to maintain.

Also consider not using vector<bool> (use a deque<bool> or a vector<char> or vector<int> instead), as it usually requires more threading overhead because it stores pseudo-bools in individual bits. That lets it fit more in less space but unfortunately means that reads and writes to the container are no longer atomic, which could require more locking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文