dynamic 锁竞争等系统开销分析
来源:互联网 发布:详情页制作软件 编辑:程序博客网 时间:2024/06/13 01:25
1. dynamic_cast
___RTDynamicCast 这个子程序里面有几百行,而且还有很多的call
pTmpBase->show();对应的汇编,加起来没有10行
call dword ptr 汇编为:
测试数据:
/*
双核机器
1千万数据 单线程, 带锁: 0秒
1亿数据
单线程, 带锁: 7秒 与没有锁比,消耗在锁的获取与释放。
双线程, 带锁: 14秒
3线程, 带锁: 14秒
10线程, 带锁: 12秒
100线程, 带锁: 11秒
1000线程,带锁: 11秒 cpu大概50到60 线程竞争同一个锁,没有竞争到的会排队进入sleep状态。
1亿数据,双线程,读写锁 27秒
对于读写锁,性能上看比互斥锁差2到3倍,所以读写锁的使用条件并不只是“当读远远次数多于写的时候”,当读的操作耗时较长的时候,而且写的次数较少的时候,才更适用。
1亿数据 单线程, 不带锁:0秒
1亿数据 一百线程,不带锁:0秒
100亿数据 单线程 不带锁 2秒
100亿数据 双线程 不带锁 3秒
100亿数据 10线程 不带锁 10秒 cpu负载99%
100亿数据 100线程 不带锁 31秒 100个线程,cpu负载99%
100亿数据 1000线程 不带锁 同上,cpu负载99%,严重影响系统其他功能
*/
1)当锁竞争与线程切换的次数不是很大的时候,这种开销可以忽略,从“双线程,带锁:14秒”来分析,多线程1千万次的锁竞争,从时间上看话费大概1秒钟多一点。
2)线程切换、锁竞争主要是消耗cpu,从时间上看,锁的竞争、获取与释放,才是花费时间的。
3)与没有锁操作比,带锁的开销从时间上看,还是差很多的,1000倍的时间开销。
4)线程切换也是很消耗cpu的,100亿数据的情况下,单线程只需2秒,100线程由于线程切换消耗太多cpu用了30多秒。
3. 迭代器
对一个10个元素的list进行1亿次遍历,30秒
对一个100个元素的list进行1千万次遍历,27秒
1亿次的迭代操作大概只花费3秒。虽然在代码编写时候,从时间上运行时间差不太多,但是cpu差距很大,不要以为用list与用map的时间差不多就用list,cpu也是一种资源。
如果1秒钟有1w的数据,那么要分析出处理一条数据用到多少锁竞争、dynamic_cast、线程切换通常这些在处理一条数据都不会很多,对系统的影响基本不会很大。最需要注意的就是程序逻辑上,比如迭代器操作有多少,假如一条数据有1000次迭代器操作,那么就是每秒1千万的迭代器操作,即时处理上cpu绰绰有余,但是对cpu消耗很大。
#include <iostream>#include <ctime>using namespace std;class Base{public:virtual void show(){};};class Derived : public Base{public:virtual void show(){};};int main(int argc, char* argv[]){Base* pTmpBase = new Derived();Derived* pTmpDerived = NULL;time_t begin = time(NULL);// 10亿次int count = 1000*1000*1000;for (int i=0; i<count; i++){// 20 秒//pTmpDerived = dynamic_cast<Derived*>(pTmpBase);// 2秒//pTmpDerived = static_cast<Derived*>(pTmpBase);// 3秒//pTmpBase->show();// 空循环,运行时间也是2~3秒内}time_t end = time(NULL);printf("Using seconds %d.\n ", end - begin);system("pause"); return 0;}
pTmpDerived = dynamic_cast<Derived*>(pTmpBase); 对应的汇编
00401091 push 000401093 push offset Derived `RTTI Type Descriptor' (004150d8)00401098 push offset Base `RTTI Type Descriptor' (004150c0)0040109D push 00040109F mov ecx,dword ptr [pTmpBase]004010A2 push ecx004010A3 call ___RTDynamicCast (00404af3)004010A8 add esp,14h004010AB mov dword ptr [pTmpDerived],eax
___RTDynamicCast 这个子程序里面有几百行,而且还有很多的call
pTmpBase->show();对应的汇编,加起来没有10行
00401091 mov ecx,dword ptr [pTmpBase]00401094 mov edx,dword ptr [ecx]00401096 mov ecx,dword ptr [pTmpBase]00401099 call dword ptr [edx]
call dword ptr 汇编为:
004011A0 push ebp004011A1 mov ebp,esp004011A3 push ecx004011A4 mov dword ptr [ebp-4],ecx004011A7 mov esp,ebp004011A9 pop ebp004011AA ret
#include <iostream>#include <ctime>#include "ace/Task.h"using namespace std;class MyTask : public ACE_Task_Base{public:MyTask(){begin = time(NULL);nCount = 0;};virtual int svc (void){while(1){//ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, obj, m_lock, -1);ACE_READ_GUARD_RETURN(ACE_RW_Thread_Mutex, obj, m_rwLock, -1);nCount++;// 1亿次if (nCount >= 1000*1000*100){time_t end = time(NULL);printf("Using seconds %d.\n ", end - begin);Sleep(1000);}}}private:ACE_Recursive_Thread_Mutex m_lock;ACE_RW_Thread_Mutex m_rwLock;time_t begin;unsigned long nCount;};int main(int argc, char* argv[]){MyTask task;int threadNum = 2;task.activate(THR_NEW_LWP | THR_JOINABLE |THR_INHERIT_SCHED, threadNum);system("pause"); return 0;}
测试数据:
/*
双核机器
1千万数据 单线程, 带锁: 0秒
1亿数据
单线程, 带锁: 7秒 与没有锁比,消耗在锁的获取与释放。
双线程, 带锁: 14秒
3线程, 带锁: 14秒
10线程, 带锁: 12秒
100线程, 带锁: 11秒
1000线程,带锁: 11秒 cpu大概50到60 线程竞争同一个锁,没有竞争到的会排队进入sleep状态。
1亿数据,双线程,读写锁 27秒
对于读写锁,性能上看比互斥锁差2到3倍,所以读写锁的使用条件并不只是“当读远远次数多于写的时候”,当读的操作耗时较长的时候,而且写的次数较少的时候,才更适用。
1亿数据 单线程, 不带锁:0秒
1亿数据 一百线程,不带锁:0秒
100亿数据 单线程 不带锁 2秒
100亿数据 双线程 不带锁 3秒
100亿数据 10线程 不带锁 10秒 cpu负载99%
100亿数据 100线程 不带锁 31秒 100个线程,cpu负载99%
100亿数据 1000线程 不带锁 同上,cpu负载99%,严重影响系统其他功能
*/
1)当锁竞争与线程切换的次数不是很大的时候,这种开销可以忽略,从“双线程,带锁:14秒”来分析,多线程1千万次的锁竞争,从时间上看话费大概1秒钟多一点。
2)线程切换、锁竞争主要是消耗cpu,从时间上看,锁的竞争、获取与释放,才是花费时间的。
3)与没有锁操作比,带锁的开销从时间上看,还是差很多的,1000倍的时间开销。
4)线程切换也是很消耗cpu的,100亿数据的情况下,单线程只需2秒,100线程由于线程切换消耗太多cpu用了30多秒。
3. 迭代器
#include <iostream>#include <ctime>#include "ace/Task.h"#include <list>using namespace std;int main(int argc, char* argv[]){std::list<int> listTmp;for (int i=0; i<100; i++){listTmp.push_back(i);}time_t begin = time(NULL);// 1亿次int count = 1000*1000*10;for (int j=0; j<count; j++){list<int>::iterator iter = listTmp.begin();for(; iter != listTmp.end(); ++iter){}}time_t end = time(NULL);printf("Using seconds %d.\n ", end - begin);system("pause"); return 0;}
对一个10个元素的list进行1亿次遍历,30秒
对一个100个元素的list进行1千万次遍历,27秒
1亿次的迭代操作大概只花费3秒。虽然在代码编写时候,从时间上运行时间差不太多,但是cpu差距很大,不要以为用list与用map的时间差不多就用list,cpu也是一种资源。
如果1秒钟有1w的数据,那么要分析出处理一条数据用到多少锁竞争、dynamic_cast、线程切换通常这些在处理一条数据都不会很多,对系统的影响基本不会很大。最需要注意的就是程序逻辑上,比如迭代器操作有多少,假如一条数据有1000次迭代器操作,那么就是每秒1千万的迭代器操作,即时处理上cpu绰绰有余,但是对cpu消耗很大。
如果1秒钟有1千万的数据,那么很多问题都会凸显出来,dynamic的系统消耗,锁竞争造成的时间浪费,任何多余的迭代器遍历操作。带宽问题。1千万的数据,假如1条数据100字节,那么需要带宽(100*1000*10000/8)bit/s 有120兆的带宽了,一般网卡上行600兆,再大可能带宽就是问题了。
一个简单对象,new和delete 1千万次,大概耗费1s。
0 0
- dynamic 锁竞争等系统开销分析
- 多线程锁竞争造成的开销
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- 多核系统中三种典型锁竞争的加速比分析
- Java面试题集(136-150)
- test1gongsi
- Docker学习笔记1
- linux下vi编辑器使用方法
- 作业3.24
- dynamic 锁竞争等系统开销分析
- [solr] - defType - 查询权重排序
- 5g的基础知识,发展及现状
- 必须Mark!最佳HTML5应用开发工具推荐
- rnnlm源码分析(八)
- poj 3694 Network (找桥,LCA)
- 计算机网络 TCP 滑动窗口协议 详解
- c++中嵌入python入门4 之 Boost.Python
- mysql enterprise backup入门使用