当前位置: 首页 > news >正文

网站建设咨询费用外发加工网1688

网站建设咨询费用,外发加工网1688,华竣国际的展厅设计公司,发布软文是什么意思目录 有关大于256KB内存的申请和释放处理方法 处理大于256KB的内存申请 补充内容1 补充内容2 补充内容3 处理大于256KB的内存释放 新增内容1 新增内容2 测试函数 使用定长内存池替代new 释放对象时不传对象大小 补充内容1 补充内容2 补充内容3 补充内容4 测试…目录 有关大于256KB内存的申请和释放处理方法  处理大于256KB的内存申请 补充内容1 补充内容2 补充内容3  处理大于256KB的内存释放 新增内容1 新增内容2 测试函数 使用定长内存池替代new 释放对象时不传对象大小 补充内容1 补充内容2 补充内容3 补充内容4 测试函数 为哈希桶加锁 多线程环境下对比malloc测试 复杂问题的调试技巧 性能瓶颈分析 针对性能瓶颈使用基数树进行优化 基数树代码 有关大于256KB内存的申请和释放处理方法  内存申请和释放大于256KB也分为两种情况 大于256KB但是小于128 * 8 * 1024KB大于128 * 8 * 1024KB 内存申请大于256KB但小于128 * 8 * 1024KB因为PageCache中存放的span所管理的最大页数为128即span可分配的最大内存为128 * 8 * 1024 KB所以当可以直接向PageCache申请一个合适的span该span管理的页数为此次内存申请对齐后大小 / 页大小 内存申请大于128 * 8 *1024 KBPageCache中已经没有合适的span了直接向堆上申请 处理大于256KB的内存申请 补充内容1 在RoundUp函数中新增用于处理大于256KB内存申请的内存对齐判断 (_RoundUp函数不变 //用于内存对齐 static inline size_t RoundUp(size_t size) {if (size 128){return _RoundUp(size, 8);}else if (size 1024){return _RoundUp(size, 16);}else if (size 8 * 1024){return _RoundUp(size, 128);}else if (size 64 * 1024){return _RoundUp(size, 1024);}else if (size 256 * 1024){return _RoundUp(size, 8 * 1024);}else{return _RoundUp(size, 1 PAGE_SHIFT);//对齐数为当前规定的页的大小} } 补充内容2 在NewSpan开始处中新增获取管理页数大于128的span的判断 //所需页数大于128PageCache无法分配需要向堆申请 if (k NPAGES - 1) {void* ptr SystemAlloc(k);//从堆获取一块内存Span* span new Span;//申请一个span结点span-_PageId (size_t)ptr PAGE_SHIFT;//新span中的页号为ptr指向的内存地址 / 页大小span-_n k;//新span中的页数为n个_idSpanMap[span-_PageId] span;//存放映射关系即使该span不会被挂在PageCache上return span; } 补充内容3  在ConcurrentAlloc函数新增size MAX_BYTES的判断 //申请内存 static void* ConcurrentAlloc(size_t size) {if (size MAX_BYTES){size_t alignSize SizeClass::RoundUp(size);//内存对齐size_t kpage alignSize PAGE_SHIFT;//计算所需页数PageCache::GetInstance()-_pageMtx.lock();Span* span PageCache::GetInstance()-NewSpan(kpage);//向PageCache申请管理kpage个页的span若kpage 128则需要经过补充内容2中的内容否则还是按照原NewSpan执行void* ptr (void*)(span-_PageId PAGE_SHIFT);//通过页号计算地址PageCache::GetInstance()-_pageMtx.unlock();return ptr;//返回从PageCache分配给的内存空间的地址}else{...//获取TLS的那部分内容} } 处理大于256KB的内存释放 新增内容1 在ReleaseSpanToPageCache开始处新增当归还的span的_n 128的判断 //大于128页的span直接还给堆 if (span-_n NPAGES - 1) {void* ptr (void*)(span-_PageId PAGE_SHIFT);SystemFree(ptr);delete span;return; } 新增内容2 在ConcurrentFree中新增用于size MAX_BYTES的判断 //释放内存 static void ConcurrentFree(void* ptr,size_t size) {if (size MAX_BYTES){Span* span PageCache::GetInstance()-MapObjectToSpan(ptr);//根据归还的内存地址获取要归还的spanPageCache::GetInstance()-_pageMtx.lock();PageCache::GetInstance()-ReleaseSpanToPageCache(span);//将要归还的span挂在PageCache上或者返还给堆PageCache::GetInstance()-_pageMtx.unlock();}else{...//还是原来的那两行释放内容} }测试函数 //用于测试内存申请和释放大于256KB void BigAlloc() {//内存申请和释放大于256KB但是小于128 * 8 * 1024KBvoid* p1 ConcurrentAlloc(257 * 1024);ConcurrentFree(p1, 257 * 1024);//内存申请和释放大于128 * 8 * 1024KBvoid* p2 ConcurrentAlloc(129 * 8 * 1024);ConcurrentFree(p2, 129 * 8 * 1024); } 使用定长内存池替代new 基本概念定长内存池在申请内存时是直接向堆申请的没有使用malloc效率得到提升而目前我们在本项目中用到到了很多new的操作其本质还是malloc因此我们要用定长内存池中的New()和Delete()函数来代替new和delete进行内存申请和释放从而提高程序执行效率  准备工作在某个涉及new或者delete的类中新增ObjectPool 类型的私有成员变量下面以PageCache为例 class PageCache { public:... private:...ObjectPoolSpan _spanPool;//中的类型根据需要进行更改... }; 替换方式将PageCache.cpp中所有使用new的地方都换成_spanPool.New()将所有使用delet的位置都换为_spanPool.Delete( ? )表示要删除的对象的名称可能是span也可能是kspan之类的 //Span* kSpan new Span; Span* kSpan _spanPool.New();//delete span; _spanPool.Delete(span); 易忽略位置 1、ConcurrentAlloc.h中的new ThreadCache //pTLSThreadCache new ThreadCache; static ObjectPoolThreadCache tcPool;//static修饰保证只在当前文件中可以被访问 pTLSThreadCache tcPool.New(); 重点  注意事项pTLSThreadCache是每个线程独有的一个对象但是为其申请空间的tcPool不是它是一个静态的对象整个进程中独一份被当前进程中的所有线程共享多线程情况下会出现线程安全问题所以这里也需要加锁不加的话有小概率不崩溃即轮到t2执行时_memory不为空 解决办法在ObjPool类中新增公有成员变量_poolMtx同时在pTLSThreadCache tcPool.New()的两侧加锁 tcPool._poolMtx.lock(); pTLSThreadCache tcPool.New(); tcPool._poolMtx.unlock(); 补充SpanList类中为了创建头结点的new Span不用替换因为头节点通常在 SpanList 对象的整个生命周期内存在并且不会像其他 Span 对象那样频繁创建和销毁。使用 _spanPool 进行内存管理主要是为了优化频繁分配和回收的对象而头节点的长生命周期使得使用 _spanPool 的优势不明显 释放对象时不传对象大小 基本概念在之前释放内存时我们不仅要传入释放的内存的地址还要存放要释放的内存的大小过于麻烦所以最好只传递一个指针即可释放内存 ConcurrentFree(p1, 6); 补充内容1 在span类中新增一个表示当前span中管理的内存的大小的成员变量_objSize struct Span {...size_t _objSize 0;//当前span管理的内存大小 }; 补充内容2 在ConcurrentFree中将MapObjectToSpan的位置进行移动并获取当前span的_objSize //释放内存 static void ConcurrentFree(void* ptr) {Span* span PageCache::GetInstance()-MapObjectToSpan(ptr);size_t size span-_objSize;if (size MAX_BYTES){...}else{...} } 补充内容3 在ConcurrentAlloc中从堆上获取到一个span后补充该span的_objSize //申请内存 static void* ConcurrentAlloc(size_t size) {if (size MAX_BYTES){...Span* span PageCache::GetInstance()-NewSpan(kpage);span-_objSize size;...}else{...} } 补充内容4 CentralCache中的NewSpan后填充该span的_objSize //为指定位置桶下的SpanList申请一个非空的span Span* CentralCache::GetOneSpan(SpanList list, size_t size) {...Span* span PageCache::GetInstance()-NewSpan(SizeClass::NumMovePage(size));//从PageCache中获取一个新的非空spanspan-_isUse true;span-_objSize size;.... } 注意事项记得最后把ConcurrentFree的第二个形参删除 测试函数 void WithNoSize() {void* p1 ConcurrentAlloc(257 * 1024);ConcurrentFree(p1);void* p2 ConcurrentAlloc(129 * 8 * 1024);ConcurrentFree(p2); } 为哈希桶加锁 基本概念C的标准模板库STL提供的容器在多线程环境下并不保证线程安全因此在多个线程同时访问或修改同一个容器时通常需要自行添加同步机制如互斥锁以确保数据的一致性和避免竞态条件因此当我们尝试在本项目中使用哈希桶记录span与页号的映射关系时需要及时的加锁 加锁位置参与读写哈希桶的函数有NewSpan、MapObjectToSpan和ReleaseSpanToPageCache它们都在PageCache.cpp中其中在CentralCache.cpp中使用这三个函数时只有MapObjectToSpan没有添加锁这就可能导致多个线程在CentralCache中同时访问MapObjectToSpan函数并同时访问哈希桶造成线程安全问题所以要在MapObjectToSpan函数执行到访问哈希桶的操作前加锁 //地址-页号-span的映射 Span* PageCache::MapObjectToSpan(void* obj) {size_t id ((size_t)obj PAGE_SHIFT);std::unique_lockstd::mutex lock(_pageMtx);auto ret _idSpanMap.find(id);if (ret ! _idSpanMap.end()){return ret-second;}else{assert(false);return nullptr;} } 关于std::unique_lockstd::mutex lock(_pageMtx)是一种通过RAII方式管理互斥锁的机制确保在多线程环境中对共享资源的安全访问。它自动处理锁的获取和释放减少了手动管理锁可能带来的错误风险同时提供了较高的灵活性适用于各种复杂的同步场景 多线程环境下对比malloc测试 新增Benchmark.cpp源文件 #includecstdio #includeiostream #includevector #includethread #includemutex #includeConcurrentAlloc.h using namespace std;void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)//ntime一轮申请和释放内存的次数,round是跑多少轮,nworks是线程数 {std::vectorstd::thread vthread(nworks);std::atomicsize_t malloc_costtime 0;std::atomicsize_t free_costtime 0;for (size_t k 0; k nworks; k){vthread[k] std::thread([, k]() {std::vectorvoid* v;v.reserve(ntimes);for (size_t j 0; j rounds; j){size_t begin1 clock();for (size_t i 0; i ntimes; i){//v.push_back(malloc(16));v.push_back(malloc((16 i) % 8192 1));}size_t end1 clock();size_t begin2 clock();for (size_t i 0; i ntimes; i){free(v[i]);}size_t end2 clock();v.clear();malloc_costtime (end1 - begin1);free_costtime (end2 - begin2);}});}for (auto t : vthread){t.join();}printf(%u个线程并发执行%u轮次每轮次malloc %u次: 花费%u ms\n,nworks, rounds, ntimes, malloc_costtime.load());printf(%u个线程并发执行%u轮次每轮次free %u次: 花费%u ms\n,nworks, rounds, ntimes, free_costtime.load());printf(%u个线程并发mallocfree %u次总计花费%u ms\n,nworks, nworks * rounds * ntimes, malloc_costtime.load() free_costtime.load()); }// 单轮次申请释放次数 线程数 轮次 void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds) {std::vectorstd::thread vthread(nworks);std::atomicsize_t malloc_costtime 0;std::atomicsize_t free_costtime 0;for (size_t k 0; k nworks; k){vthread[k] std::thread([]() {std::vectorvoid* v;v.reserve(ntimes);for (size_t j 0; j rounds; j){size_t begin1 clock();for (size_t i 0; i ntimes; i){//v.push_back(ConcurrentAlloc(16));v.push_back(ConcurrentAlloc((16 i) % 8192 1));}size_t end1 clock();size_t begin2 clock();for (size_t i 0; i ntimes; i){ConcurrentFree(v[i]);}size_t end2 clock();v.clear();malloc_costtime (end1 - begin1);free_costtime (end2 - begin2);}});}for (auto t : vthread){t.join();}printf(%u个线程并发执行%u轮次每轮次concurrent alloc %u次: 花费%u ms\n,nworks, rounds, ntimes, malloc_costtime.load());printf(%u个线程并发执行%u轮次每轮次concurrent dealloc %u次: 花费%u ms\n,nworks, rounds, ntimes, free_costtime.load());printf(%u个线程并发concurrent allocdealloc %u次总计花费%u ms\n,nworks, nworks * rounds * ntimes, malloc_costtime.load() free_costtime.load()); } int main() {size_t n 10000;cout endl;BenchmarkConcurrentMalloc(n, 10, 10);cout endl endl;BenchmarkMalloc(n, 10, 10);cout endl;return 0; } 性能瓶颈分析 针对性能瓶颈使用基数树进行优化 基数树代码 ~over~
http://www.yayakq.cn/news/4462/

相关文章:

  • 继续访问这个网站互联网舆情忻州
  • 如何建设网站论坛高端私人订制网站建设
  • 建设部物业证书查询官方网站悬停提示 wordpress
  • 上海建设摩托车官方网站店铺详情页设计
  • 台州网站策划台州网站策划写作平台有哪些
  • 网站建设图标图片湖北建设网
  • 网站打开很慢怎么做优化手机网站底部导航
  • 外贸soho怎么做网站做海外购网站
  • dw做网站首页怎么做网页设计与网站的关系
  • 罗湖区网站公司ui设计培训班需要学几个月
  • 网站建设评审验收会议主持词做企业网站和邮箱
  • 阿克苏网站开发牛魔王网站建设
  • 加强检察门户网站建设情况文档阅读网站模板下载
  • 做高仿网站网站建设与设计ppt模板
  • 厦门哪家做网站好电子商务网站开发环境示范
  • 周口网站设计网站做的一样算不算侵权
  • 网站建设提供书面资料清单Wordpress4.0参考手册.CHM
  • APP和网站是一样吗网站转化路径
  • 网站页面切换效果长春网站建设技术外包
  • 自己搭建服务器做网站网站网络排名优化方法
  • 如何做网站首页图电商发展趋势和未来
  • 网站备案查询工具xenforo和wordpress
  • 微网站首选公司淘宝客推广有效果吗
  • 短裙怎么做视频网站沧州国外网站建设
  • 网站域名是不是网址在线生成电子印章
  • ps做网站logo门户网站建站系统
  • 5个免费安全的资源网站建设通下载
  • 物联网技术应用专业是学什么的广州seo代理计费
  • 网站seo 优帮云wordpress网站搬家图片路径
  • 物流网站查询阅读的网站建设需要多少钱