c++ boost函数 多进程 多线程 效率问题

seacat_hello 2012-06-19 09:22:37
现在我使用了c++ boost中的trim函数,发现该函数在单个线程下性能不错。
但是如果我在多线程环境中调用该函数(不同线程之间没有信息交互),发现速度非常慢。
如果使用多进程,每个进程一个线程调用trim函数,执行时间和单个进程时间一样。

另外,我也写了一个简单的trim函数,并测试了起在多线程和多进程的表现,发现执行时间没有太大的区别。

求教大神,是什么原因导致了该问题。 boost trim函数在多线程环境下存在瓶颈吗?还是使用的时候需要注意什么?

硬件环境:操作系统 linux redhat 6.1, cpu 8核,内存 24G。
demo代码如下,大家在测试的时候线程个数可以根据机器的配置进行调整

test1.cpp,多线程调用boost trim函数

using namespace std;
using namespace boost;

void *TrimNString(void *arg) {

string base ="fdsffdsafdsa";
for(int i = 0; i != 50000000;i++)
{
string str = base;
trim(str);
}
return 0;
}

int main()
{

//例如开8个线程
system("date");
pthread_t mythread1, mythread2, mythread3, mythread4, mythread5, mythread6, mythread7,mythread8;
pthread_create(&mythread1, NULL, TrimNString, NULL);
pthread_create(&mythread2, NULL, TrimNString, NULL);
pthread_create(&mythread3, NULL, TrimNString, NULL);
pthread_create(&mythread4, NULL, TrimNString, NULL);
pthread_create(&mythread5, NULL, TrimNString, NULL);
pthread_create(&mythread6, NULL, TrimNString, NULL);
pthread_create(&mythread7, NULL, TrimNString, NULL);
pthread_create(&mythread8, NULL, TrimNString, NULL);

pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
pthread_join(mythread3, NULL);
pthread_join(mythread4, NULL);
pthread_join(mythread5, NULL);
pthread_join(mythread6, NULL);
pthread_join(mythread7, NULL);
pthread_join(mythread8, NULL);
system("date");
return 0;
}


test2.cpp,多进程调用boost trim函数

/*
* test.cpp
*
* Created on: 2012-6-19
* Author: root
*/



#include<pthread.h>
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;
using namespace boost;


void *TrimNString(void *arg) {

system("./TrimNString");//其中TrimNString的可执行文件请参照test3.cpp


return 0;
}

int main()
{

//进程trim实现方式
system("date");
pthread_t mythread1, mythread2, mythread3, mythread4, mythread5, mythread6, mythread7,mythread8;
pthread_create(&mythread1, NULL, TrimNString, NULL);
pthread_create(&mythread2, NULL, TrimNString, NULL);
pthread_create(&mythread3, NULL, TrimNString, NULL);
pthread_create(&mythread4, NULL, TrimNString, NULL);
pthread_create(&mythread5, NULL, TrimNString, NULL);
pthread_create(&mythread6, NULL, TrimNString, NULL);
pthread_create(&mythread7, NULL, TrimNString, NULL);
pthread_create(&mythread8, NULL, TrimNString, NULL);

pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
pthread_join(mythread3, NULL);
pthread_join(mythread4, NULL);
pthread_join(mythread5, NULL);
pthread_join(mythread6, NULL);
pthread_join(mythread7, NULL);
pthread_join(mythread8, NULL);
system("date");
return 0;
}




单个进程执行代码,供test2.cpp调用

#include<pthread.h>
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;
using namespace boost;


//生成可执行文件TrimNString供test2.cpp调用
int main()
{
string base ="fdsffdsafdsa";
for(int i = 0; i != 50000000;i++)
{
string str = base;
trim(str);
}
return 0;
}



test4.cpp,多线程调用自定义trim函数,和多进程执行时间差不多


#include<pthread.h>
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;
using namespace boost;

void ltrim(string & str)
{
if(str.find_first_not_of(" \n\r\t") != string::npos)
{
str = str.substr(str.find_first_not_of(" \n\r\t"));
}

}

void rtrim(string & str)
{
if(str.find_first_not_of(" \n\r\t") != string::npos)
{
str = str.substr(0, str.find_last_not_of(" \n\r\t") + 1);
}

}

void trimStr(string &str)
{
ltrim(str);
rtrim(str);
}

void *TrimNString(void *arg) {

string base ="fdsffdsafdsa";
for(int i = 0; i != 50000000;i++)
{
string str = base;
trimStr(str);
}
return 0;
}

int main()
{

//例如开8个线程
system("date");
pthread_t mythread1, mythread2, mythread3, mythread4, mythread5, mythread6, mythread7,mythread8;
pthread_create(&mythread1, NULL, TrimNString, NULL);
pthread_create(&mythread2, NULL, TrimNString, NULL);
pthread_create(&mythread3, NULL, TrimNString, NULL);
pthread_create(&mythread4, NULL, TrimNString, NULL);
pthread_create(&mythread5, NULL, TrimNString, NULL);
pthread_create(&mythread6, NULL, TrimNString, NULL);
pthread_create(&mythread7, NULL, TrimNString, NULL);
pthread_create(&mythread8, NULL, TrimNString, NULL);

pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
pthread_join(mythread3, NULL);
pthread_join(mythread4, NULL);
pthread_join(mythread5, NULL);
pthread_join(mythread6, NULL);
pthread_join(mythread7, NULL);
pthread_join(mythread8, NULL);
system("date");
return 0;
}



...全文
712 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingcairousi 2012-06-21
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

回复qingcairousi:我看过boost的代码trim代码
其核心的思想主要是调用trim_detail的函数,获取第一个不是空白的位置,然后通过string 本身的erase删除前面的空格。 而我写的代码是用string的 substring 获取字符串,就这个区别而已。
[/Quote]
string的erase可能涉及到free或者delete,这就牵涉到标准库的内存管理的问题了。你可以用一个自定义allocator的string替换std::string来试试看会有什么变化。
seacat_hello 2012-06-21
  • 打赏
  • 举报
回复
哎,csdn别让我失望啊。难道这个问题大家没有遇到过吗?
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

引用 14 楼 的回复:
回复pengzhixi:
所有的操作都是string 的,那是用这些操作本身也是需要考虑一些效率吧。


那你觉得 trim调用string的这些操作对效率的影响有多大呢?
[/Quote]

的确不应该影响到 其在多线程和多进程下执行时间。
但现在观测到,其执行时间有区别,关键这个执行时间在两中环境下还差很多。
pengzhixi 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
回复pengzhixi:
所有的操作都是string 的,那是用这些操作本身也是需要考虑一些效率吧。
[/Quote]

那你觉得 trim调用string的这些操作对效率的影响有多大呢?
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
回复pengzhixi:
所有的操作都是string 的,那是用这些操作本身也是需要考虑一些效率吧。
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
回复qq120848369:
你的意思是我需要调用pthread_setaffinity_np,设置线程绑定到多核吗? 但这样做知识回避了问题,并没有解决这个问题。
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
回复qingcairousi:我看过boost的代码trim代码
其核心的思想主要是调用trim_detail的函数,获取第一个不是空白的位置,然后通过string 本身的erase删除前面的空格。 而我写的代码是用string的 substring 获取字符串,就这个区别而已。

qq120848369 2012-06-20
  • 打赏
  • 举报
回复
NAME
pthread_setaffinity_np, pthread_getaffinity_np - set/get CPU affinity of a thread

SYNOPSIS
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <pthread.h>

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize,
cpu_set_t *cpuset);

Compile and link with -pthread.


设置线程绑定到多核。

NAME
sched_setaffinity, sched_getaffinity - set and get a process’s CPU affinity mask

SYNOPSIS
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>

int sched_setaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t *mask);

int sched_getaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t *mask);


设置进程绑定到多核。

NAME
sysconf - Get configuration information at runtime

SYNOPSIS
#include <unistd.h>

long sysconf(int name);

- _SC_NPROCESSORS_CONF
The number of processors configured.

- _SC_NPROCESSORS_ONLN
The number of processors currently online (available).



获取CPU核心数目。
qingcairousi 2012-06-20
  • 打赏
  • 举报
回复
最有可能的是在循环中,string本身不断地在申请和释放内存,而在多线程环境下,标准库的内存管理可能存在竞争条件。
所以就造成了多线程下的性能下降。
pengzhixi 2012-06-20
  • 打赏
  • 举报
回复
boost中的trim函数没有做任何其他的事情,所有的操作都是使用了string本身自带的。所以不是trim的问题
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
回复pengzhixi:
我写的这个简单的trim函数,也用了string啊。
如果是stl string 的问题,我写的这个trim函数,同样应该存在问题。
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
回复zhao4zhong1:

其实我不需要准确的执行时间。

现在的情况是,在多线程的环境下,例如说3个线程,boost trim函数执行时间是单线程trim函数的3倍时间。
多进程环境,则没有区别。

赵4老师 2012-06-20
  • 打赏
  • 举报
回复
不看对应汇编指令,不Profile,谁能准确分析一个函数执行时的性能?
pengzhixi 2012-06-20
  • 打赏
  • 举报
回复
这恐怕在于string本身在多线程下的效率问题了。
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
为啥我在刚进版的时候看到的回帖数目少一个啊.
seacat_hello 2012-06-20
  • 打赏
  • 举报
回复
回复taodm:能力有限啊,看了源码以后还是不知道为什么....
taodm 2012-06-19
  • 打赏
  • 举报
回复
自己打开boost的源码看看不就知道了。

64,668

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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