我正在用C++编写一个程序来执行特定系统的模拟.对于每个时间步长,执行的最大部分是由单个循环占用.幸运的是,这是非常平行的,所以我决定使用Boost Threads并行化它(我在2核机器上运行).我期望加速接近串行版本的2倍,因为没有锁定.但是我发现根本没有加速.
我实现了循环的并行版本如下:
然后每个线程执行以下操作:
主线程等待工作完成障碍.
我使用这种方法,因为它应该提供良好的负载平衡(因为每次计算可能需要不同的时间量).我真的很好奇可能导致这种放缓的原因.我总是读到原子变量很快,但现在我开始怀疑它们是否有性能成本.
如果有人有什么想法或任何提示,我会非常感激.我一直在抨击它一个星期,并且剖析没有透露太多.
编辑:问题解决了! 我将详细说明我是如何解决这个问题的.我再次使用gprof,但这次编译时没有优化标志(-O3).然后,分析器立即表明我在函数中花费了不可思议的时间,该函数对每个单独的粒子执行计算:远远超过串行版本.
此功能是虚拟的,可以多态访问.我改变了代码直接访问它,而不是通过vtable和voila'并行版本产生了近2的加速!串行版本的相同更改几乎没有影响.
我不知道为什么会这样,如果有人知道的话会感兴趣!
感谢所有的海报.你们都在某种程度上有所帮助,接受一个答案是非常困难的.
parallel-processing performance multithreading boost-thread atomic-values
是否可以在Boost线程中设置CPU亲和力((即,将每个线程设置为在不同的CPU上运行)?您是否可以对此提出任何教程/文档?在以下示例中,除了以下线程外,Google搜索不会返回太多信息(boost-bind_processor.v1.tar.gz)不再存在于文件服务器中。
我试图在一个线程中抛出异常并允许调用进程捕获它.但是,这似乎会导致整个应用程序崩溃.请参阅附加的测试代码,永远不会打印退出语
1 #include <boost/thread.hpp>
2 #include <iostream>
3
4 void wait(int seconds)
5 {
6 boost::this_thread::sleep(boost::posix_time::seconds(seconds));
7 }
8
9 void thread()
10 {
11 for (int i = 0; i < 5; ++i)
12 {
13 wait(1);
14 std::cout << i << std::endl;
15 }
16 throw;
17 }
18
19 int main()
20 {
21 try
22 {
23 boost::thread t(thread);
24 t.join();
25 std::cout << "Exit normally\n";
26 }
27 catch (...)
28 {
29 std::cout << …Run Code Online (Sandbox Code Playgroud) multithreading boost exception-handling exception boost-thread
我是多线程编程的新手,并且对Mutex如何工作感到困惑.在Boost :: Thread手册中,它指出:
互斥锁保证只有一个线程可以锁定给定的互斥锁.如果代码段被互斥锁定和解锁包围,则可以保证一次只有一个线程执行该段代码.当该线程解锁互斥锁时,其他线程可以进入该代码区域:
我的理解是,Mutex用于保护一段代码不被多个线程同时执行,不保护变量的内存地址.我很难掌握这个概念,如果我有2个不同的函数试图写入相同的内存地址会发生什么.
在Boost库中有这样的东西:
谢谢.
我有以下两个代码段.第一个块编译并按预期工作.但是第二个块不能编译.
我的问题是,根据下面的代码,尝试基于被shared_ptr代理的对象的实例创建线程时,正确的语法是什么?
#include <iostream>
#include <new>
#include <memory>
#include <boost/thread.hpp>
struct foo
{
void boo() {}
};
int main()
{
//This works
{
foo* fptr = new foo;
boost::thread t(&foo::boo,fptr);
t.join();
delete fptr;
}
//This doesn't work
{
std::shared_ptr<foo> fptr(new foo);
boost::thread t(&foo::boo,fptr);
t.join();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
Error 5 error C2784: 'T *boost::get_pointer(T *)' : could not deduce template argument for 'T *' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 3 error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> …Run Code Online (Sandbox Code Playgroud) 经过大量的搜索和一些尝试和失败后,我总结了一些事情,这就是结果:
boost::thread做boost::thread 可以被认为是Posix线程库的包装器,或者如果你愿意的话,它可以被认为是实际上没有关于线程库的真正选择,它们实际上并没有那么不同,它们更像是前一个的演化. .现在我问,如果是这种情况,我应该从哪里开始?
例如,本书明确面向C++ 11标准线程库,它为您提供了基础知识,但是您可能永远不会在现实生活中使用它,因为C++ 11线程支持仍然不是很好.最受欢迎的编译器,它在功能方面确实很差.
我认为可以说从boost::thread今天的世界开始是一个很好的选择 - 如果我错了就纠正我 - 这也是多平台支持和C++ 03遗留支持的唯一真正选择:我的问题是我真的找不到一本关于并发和多线程的书或参考文章看起来恰到好处,或者它只是足够好boost:thread.
你能推荐一本以并发为主的书boost::thread吗?
我有两个线程试图锁定相同的boost::mutex.其中一个线程是连续处理一些数据,另一个是周期性地显示当前状态.根据我的意图,处理线程非常频繁地释放锁并重新获取它,以便显示线程可以在需要时接入并获取它.所以,显然,我希望显示线程在下一次由进程线程释放时获取锁.但是,它没有这样做,相反,它等待锁定并且仅在来自进程线程的许多锁定释放循环之后获取它.
请检查说明我的问题的最小例子:
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
using namespace boost;
mutex mut;
void process() {
double start = time(0);
while(1) {
unique_lock<mutex> lock(mut);
this_thread::sleep(posix_time::milliseconds(10));
std::cout<<".";
if(time(0)>start+10) break;
}
}
int main() {
thread t(process);
while(!t.timed_join(posix_time::seconds(1))) {
posix_time::ptime mst1 = posix_time::microsec_clock::local_time();
cout<<endl<<"attempting to lock"<<endl;
cout.flush();
unique_lock<mutex> lock(mut);
posix_time::ptime mst2 = posix_time::microsec_clock::local_time();
posix_time::time_duration msdiff = mst2 - mst1;
cout << std::endl<<"acquired lock in: "<<msdiff.total_milliseconds() << endl;
cout.flush();
}
}
Run Code Online (Sandbox Code Playgroud)
编译: g++ mutextest.cpp -lboost_thread -pthread
当我运行可执行文件时,示例输出如下所示:
...................................................................................................
attempting to …Run Code Online (Sandbox Code Playgroud) 是否有可能以十进制或八进制格式cout thread :: id?
std::cout << std::showbase;
cout << dec(or oct) << boost::this_thread::get_id()
Run Code Online (Sandbox Code Playgroud)
我总是十六进制,例如0xdf08.
我在工作线程中捕获中断时遇到问题.这里有很多提升线程中断帖子但是,它们似乎是愚蠢的错误(我确定我的问题也是如此),或者什么都没有帮助
在我的示例中有一个创建工作线程的主线程.主线程等待用户在工作线程处于while循环时按Enter键,并以1秒的间隔休眠.当用户按下enter键时,主线程中断工作线程,然后调用join,工作线程应该在boost :: this_thread :: sleep_for(sec)处抛出一个thread_interrupted异常,应该被捕获,然后工作者函数应该退出.这允许主线程继续然后退出程序.
#define BOOST_THREAD_USE_LIB 1
#define BOOST_SYSTEM_NO_DEPRECATED 1
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <boost/thread.hpp>
#include <boost/chrono/include.hpp>
#include <boost/chrono/duration.hpp>
#include <iostream>
using namespace std;
void ThreadFunctionSleep()
{
cout << boost::this_thread::get_id() << " worker thread " << endl;
int counter = 0;
while(1)
{
cout << boost::this_thread::get_id() << " thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
boost::chrono::seconds sec(1);
boost::this_thread::sleep_for(sec);
}
catch(boost::thread_interrupted&)
{
cout << …Run Code Online (Sandbox Code Playgroud) 所以我正在编写这个整洁的小程序来自学线程,我正在使用boost :: thread和C++这样做.
我需要主线程与工作线程进行通信,为此我一直在使用全局变量.它按预期工作,但我不禁感到有点不安.
如果工作线程在主线程正在读取值的同时尝试写入全局变量,该怎么办?这是不好的,危险的,或希望在幕后考虑?
boost-thread ×10
c++ ×8
boost ×3
c++11 ×3
concurrency ×2
cpu ×1
exception ×1
linux ×1
mutex ×1
performance ×1
pthreads ×1
shared-ptr ×1