c – OpenMP创建了太多线程

weixin_38049770 2019-09-12 01:58:49
我不确定为什么OpenMP使用这么多线程.它似乎与Microsoft实现无关,因为我也尝试过显示相同行为的英特尔库.我的代码中有一些并行部分是计算绑定的,不应该创建和使用比我有内核更多的线程.但我观察到的是,对于n个启动线程,OpenMP创建了n * Cores线程.这看起来像一个大线程泄漏给我. 如果我执行在服务器上运行的“小”32位应用程序,它可能会失败,因为1000个OpenMP线程需要2 GB的地址空间已经没有为应用程序留下内存.这不应该发生.我期望从最先进的线程池重用其线程并带走不再使用的线程. 我曾尝试使用omp_set_num_threads(8)将线程池大小限制为8个核心,但这似乎只限制每个启动线程实例的线程数.我做错了还是OpenMP不是故意用这种方式的? 在我的8核机器上,我的AsyncWorker类中的5个启动线程将分配由OpenMP创建的38个线程.我希望只创建8个线程,这些线程应该在所有5个启动线程中重用. #include <atomic> #include <thread> #include <omp.h> #include <chrono> #include <vector> #include <memory> class AsyncWorker { private: std::vector<std::thread> threads; public: AsyncWorker() { } void start() // add one thread that starts an OpenMP parallel section { threads.push_back(std::thread(&AsyncWorker::threadFunc, this)); } ~AsyncWorker() { for (auto &t : threads) { t.join(); } } private: void threadFunc() { std::atomic<int> counter; auto start = std::chrono::high_resolution_clock::now(); std::chrono::milliseconds durationInMs; while (durationInMs.count() <5000l) { // each instance seems to get its own thread pool. // Why? And how can I limit the threadpool to the number of cores and when will the threads be closed? #pragma omp parallel { counter++; auto stop = std::chrono::high_resolution_clock::now(); durationInMs = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start); } } } }; int main() { //omp_set_dynamic(0); //omp_set_nested(0); //omp_set_num_threads(8); { AsyncWorker foo; foo.start(); // 1 foo.start(); // 2 foo.start(); // 3 foo.start(); // 4 foo.start(); // 5 system("pause"); } return 0; }
...全文
53 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38050362 2019-09-12
  • 打赏
  • 举报
回复
OpenMP并不意味着以这种方式使用.混合使用OpenMP和其他线程方法是灾难的一种方法,除非非常仔细地进行.即便如此,结果也是不可预测的. OpenMP标准故意不再定义这种互操作性,供应商可以按照自己认为合适的方式自由提供(如果他们认为合适的话). omp_set_num_threads(8)不会按照您的想法执行操作.它设置当没有num_threads()子句时当前线程遇到的并行区域的线程数.此外,omp_set_nested(0)已经(或可能没有),因为您没有从OpenMP线程启动并行区域,而是从C 11线程启动.可以通过OMP_THREAD_LIMIT环境变量设置OpenMP线程总数的全局限制,但这仅在OpenMP 3.0及更高版本中可用,并且MSVC(永远?)卡在OpenMP 2.0时代. 可能的行动方针是: >使用共享队列结构和OpenMP线程实现您对OpenMP 2.0的自己的任务,这些线程在循环中将工作项队列化>将OpenMP替换为Intel Threading Building Blocks – 它是开源的,支持Windows,Linux,OS X和Android上的各种编译器>用来自Concurrency Runtime的微软PPL取代OpenMP,它基本上提供了TBB的非便携式子集

476

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧