在专用线程中清除STL

时间:2011-02-03 16:50:35

标签: c++ multithreading stl c++11

在我的一个项目中,我发现呼叫std::deque<T>::clear()是一个主要瓶颈。

因此,我决定在专用的低优先级线程中移动此操作:

template <class T>
void SomeClass::parallelClear(T& c)
{
    if (!c.empty())
    {
        T* temp = new T;
        c.swap(*temp);   // swap contents (fast)

        // deallocate on separate thread
        boost::thread deleteThread([=] () { delete temp; } );

        // Windows specific: lower priority class
        SetPriorityClass(deleteThread.native_handle(), BELOW_NORMAL_PRIORITY_CLASS);
    }
}

void SomeClass:clear(std::deque<ComplexObject>& hugeDeque)
{
   parallelClear(hugeDeque);
}

这似乎工作正常(VisualC ++ 2010),但我想知道我是否忽略了任何重大缺陷。我欢迎您就上述代码发表意见。

其他信息

从GUI线程调用

SomeClass:clear(),并且在调用返回之前用户界面没有响应。另一方面,hugeQueue在清除后几秒内不可能被该线程访问。

3 个答案:

答案 0 :(得分:2)

仅当您保证对堆的访问被序列化时,这才有效。默认情况下,Windows 序列化对主堆的访问,但是可以关闭此行为,并且无法保证它跨平台或库保留。因此,我要小心取决于它 - 确保明确指出它取决于线程之间共享的堆,并且堆是可以线程安全访问的。

我个人建议使用自定义分配器来匹配分配/解除分配模式,这将是最好的性能改进 - 记住创建线程有一个非平凡的开销。

编辑:如果您正在使用GUI /工作线程样式线程设计,那么您应该创建,管理销毁工作线程上的双端队列。

答案 1 :(得分:1)

请注意,它不确定这会改善应用程序的整体性能。 Windows标准堆(也称为低碎片堆)没有用于频繁地将分配信息从一个线程传输到另一个线程。这样可行,但可能会产生相当大的处理开销。

囤积内存分配器的文档可能是一个更深入的起点: http://www.cs.umass.edu/~emery/hoard/hoard-documentation.html

您的方法虽然可以提高响应能力等。

答案 2 :(得分:0)

除了其他海报提到的内容之外,你应该考虑集合中包含的对象是否具有线程亲和性,例如单线程单元中的COM对象可能不适合这种技巧。