直到现在我在我的项目中使用std::queue
。我测量了此队列上特定操作所需的平均时间。使用Boost.Lockfree队列比使用互斥体要慢
时间是在2台机器上测得的:我的本地Ubuntu VM和远程服务器。 使用std::queue
,两台机器的平均值几乎相同:〜750微秒。
然后,我将std::queue
“升级”为boost::lockfree::spsc_queue
,这样我就可以摆脱保护队列的互斥锁。在我的本地虚拟机上,我可以看到巨大的性能增益,平均值现在在200微秒。然而,在远程机器上,平均达到800微秒,比以前要慢。
首先我想这可能是因为远程计算机可能不支持无锁的实现:
并非所有的硬件支持一组相同的原子指令。如果硬件不可用,则可以使用警卫软件进行仿真。然而,这具有失去无锁物业的明显缺点。
要了解这些指令是否受支持,boost::lockfree::queue
有一个名为bool is_lock_free(void) const;
的方法。 但是,boost::lockfree::spsc_queue
没有这样的功能,对我来说,这意味着它不依赖于硬件,并且始终是无锁的 - 在任何机器上。
什么可能是性能损失的原因?
Exmple代码(生产者/消费者)
// c++11 compiler and boost library required
#include <iostream>
#include <cstdlib>
#include <chrono>
#include <async>
#include <thread>
/* Using blocking queue:
* #include <mutex>
* #include <queue>
*/
#include <boost/lockfree/spsc_queue.hpp>
boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024>> queue;
/* Using blocking queue:
* std::queue<int> queue;
* std::mutex mutex;
*/
int main()
{
auto producer = std::async(std::launch::async, [queue /*,mutex*/]()
{
// Producing data in a random interval
while(true)
{
/* Using the blocking queue, the mutex must be locked here.
* mutex.lock();
*/
// Push random int (0-9999)
queue.push(std::rand() % 10000);
/* Using the blocking queue, the mutex must be unlocked here.
* mutex.unlock();
*/
// Sleep for random duration (0-999 microseconds)
std::this_thread::sleep_for(std::chrono::microseconds(rand() % 1000));
}
}
auto consumer = std::async(std::launch::async, [queue /*,mutex*/]()
{
// Example operation on the queue.
// Checks if 1234 was generated by the producer, returns if found.
while(true)
{
/* Using the blocking queue, the mutex must be locked here.
* mutex.lock();
*/
int value;
while(queue.pop(value)
{
if(value == 1234)
return;
}
/* Using the blocking queue, the mutex must be unlocked here.
* mutex.unlock();
*/
// Sleep for 100 microseconds
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
consumer.get();
std::cout << "1234 was generated!" << std::endl;
return 0;
}
请考虑增加一个[MCVE],允许您重现性能测量。这将允许一个更实际的答案。 – Zulan
鉴于对这个问题的高度兴趣,真正令人遗憾的是,两种不同系统的性能差异的核心方面是无法回答的。如果问题得到改善,我认为对于具体的实际答案来说,有更多的可能性。 – Zulan
@Zulan我会尽快添加一个具体的例子。 – Bobface