并发::并行端口开销和性能命中率(经验法则)

concurrency::parallel_sort overhead and performance hit (rule of thumb)?

本文关键字:经验法则 命中率 并行端口 开销 并发 性能      更新时间:2023-10-16

最近我偶然发现了一个非常大的性能改进——我说的是4倍的改进——只修改了一行代码。我刚刚将std::sort调用更改为concurrenty_parallel sort

// Get a contiguous vector copy of the pixels from the image.
std::vector<float> vals = image.copyPixels();
// New, fast way.  Takes 7 seconds on a test image.
concurrency::parallel_buffered_sort(vals.begin(), vals.end());
// Old, slow way -- takes 30 seconds on a test image
// std::sort(vals.begin(), vals.end());

这是一张大图像,我的处理时间从30秒减少到了7秒。然而,有些情况会涉及小图像。我不知道我是否可以或者应该盲目地这样做。

我想明智地使用parallel_sort、parallel_fo等,但我想知道在它成为帮助而不是阻碍之前,需要跨越什么阈值(根据要排序/迭代的元素数量)。

我最终会经历一些漫长的性能测试,但目前我没有太多时间去做。我希望在"大多数"时间里都能让它更好地工作,并且在任何时候都不会影响性能(或者至少很少)。

在这方面有经验的人能给我一个合理的经验法则吗?这在"大多数"情况下都会对我有所帮助?一个存在吗?

RandomIterator的要求以及带有const size_t _Chunk_size = 2048参数的重载的存在(控制序列化的阈值)意味着库作者意识到了这一问题。因此,可能仅仅使用concurrency::parallel_*作为std::*的插入式替换就可以了。

以下是我的想法,windows线程调度时间在工作站上约为20-60毫秒,在服务器上约为120毫秒,所以在这么长的时间内可以完成的任何事情都不需要并发。

所以,我猜在1k-10k的范围内,你对std::sort很满意。启动多个线程的延迟可能会被高估,但10k以后,使用并行排序或p缓冲排序(如果你能负担得起的话)有明显的优势,并行基数排序可能对非常大的值非常好。

注意事项适用o)

我不知道concurrency命名空间,但任何合理的并行算法实现都会适当地适应输入的大小。您不必担心底层线程实现的细节。就这么做吧。