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

新余做网站的公司适合ps做图的素材网站有哪些

新余做网站的公司,适合ps做图的素材网站有哪些,广州安全教育平台入口,长春建筑学院五、central cache的设计 central cache 也是一个哈希桶结构,与 thread cache 的映射结构相同。但不同之处在于,central cache 每个哈希桶挂载的是 SpanList 链表结构。每个 Span 节点,指向的是由一块大内存切割出来的,对应大小的…

五、central cache的设计

central cache 也是一个哈希桶结构,与 thread cache 的映射结构相同。但不同之处在于,central cache 每个哈希桶挂载的是 SpanList 链表结构。每个 Span 节点,指向的是由一块大内存切割出来的,对应大小的小内存块的自由链表结构,如 8Byte 的桶中,每个 Span 节点指向 8Byte 内存大小的自由链表;256KB 的桶中,每个 Span 节点指向 256KB 内存大小的自由链表。

CentralCache1

Span 节点所指向的内存块,是由 page cache 中按页划分得到的一块连续内存空间。一开始,每个桶内只有一个 Span,当一个 Span 拥有的内存被使用完毕后,SpanList 会创建新的 Span 节点,从 page cache 中划分新的内存过来使用。当有内存使用完毕进行归还时,将原先拿走的内存重新挂载到原 Span 节点中,即向谁借的内存,就归还给谁。这就能解释 SpanList 中有多个 Span 节点都拥有剩余的内存资源的情况。

2. 设计细节

2.1 单例模式

central cache 不需要让线程独有,所以我们就设计成只允许存在一个 central cache 即可。

class CentralCache
{
public:static CentralCache* GetInstance(){return &_instance;}
private:CentralCache() {};CentralCache(const CentralCache&) = delete;
};

2.2 桶锁保证线程安全

在 central cache 中,为了保证线程安全,必须进行加锁。但如果采用一个全局锁,会严重影响并发性能。所以,我们设计 central cache 的每个哈希桶中都有独立的桶锁(bucket lock)。这样即使有多个线程同时访问 central cache,如果它们访问的是 central cache 里不同的桶,就不会产生线程安全问题;而如果有线程访问了相同的哈希桶,也会被桶锁阻塞在外面

在 TCMalloc 的实现中,CentralFreeList 通常按 size class 数量划分,比如有 88 个 size class,就有 88 个桶锁。这种设计叫做 fine-grained locking(细粒度锁),是性能优化中常用的一种并发控制策略。

2.3 条件编译

在 thread cache 的设计中,我们能通过巧妙的代码设计来同时适配 32 位和 64 位系统,但在 central cache 的代码实现中,就不得不使用条件编译来适配不同的系统了。Windows 环境下,有一个宏 _WIN32 表示 Win32 位系统,和一个 _WIN64 表示 Win64 位系统。但问题是,在 Win32 配置下,_Win32 有定义,_Win64 无定义;在 Win64 配置下,_Win32 和 _Win64 均有定义。所以我们要想将 Win32 和 Win64 区分出来,必须严格控制条件编译的顺序才能实现。

#ifdef _Win64
typedef unsigned long long PAGE_ID;
#elif _Win32
typedef size_t PAGE_ID
#endif

2.4 central cache申请内存

central cache 通过 SpanList + Freelist 的结构管理内存。每个 size class 对应一个 SpanList ,用于管理多个来源于 page cache 的 Span。每个 Span 内部包含一个自由链表(freelist),用于记录尚未分配的小对象。当 thread cache 请求内存时,central cache 可以直接将已经切分好的对象链表批量返回,避免了 thread cache 进行对象切分的开销。当当前 SpanList 中的可用对象不足时,central cache 会向 page cache 申请新的 span,并挂载到对应的 SpanList 中,便于后续统一回收与管理。

2.5 central cache归还内存

central cache 在整个内存池中作为中间结构,其归还内存的函数涉及到三个 cache 的内容, ReleaseListToSpans() 最初由 thread cache 调用归还内存给 central cache,thread cache 的内存是由 central cache 的 span 切分并构建自由链表结构分配的。所以在归还内存时,ReleaseListToSpans() 会将被归还的小内存块重新拼接成到原来的 span,直到这个 span 恢复到初始的大小(通过计数器 useCount 实现),就将这个 span 归还给 page cache

3. 代码实现

3.1 SpanList

SpanList 的结构实现放在了 Common.h 中,这是因为 SpanList 在 page cache 中也有用到。其每一个节点 Span 中包含了以下信息:

class Span
{
public:PAGE_ID _pageID = 0;	//大块内存起始页的页号size_t _pageNum = 0;	//页的数量Span* _next = nullptr;Span* _prev = nullptr;size_t _useCount = 0;	//小内存块分配给thread cache的计数void* _freeList = nullptr;	//小内存块的自由链表
};

3.2 CentralCache.h和CentralCache.cpp

central cache 使用了单例模式实现。

CentralCache.h:

#pragma once
#include "PageCache.h"
#include "Common.h"class CentralCache
{
public:static CentralCache* GetInstance(){return &_instance;}Span* GetOneSpan(SpanList& list, size_t byte_size);size_t FetchRangeObj(void*& start, void*& end, size_t bachNum, size_t size);void ReleaseListToSpans(void* start, size_t byte_size);
private:CentralCache() {};CentralCache(const CentralCache&) = delete;private:SpanList _spanLists[NFREELIST];static CentralCache _instance;
};

CentralCache.cpp:

#include "CentralCache.h"CentralCache CentralCache::_instance;//获得一个非空的span
Span* CentralCache::GetOneSpan(SpanList& list, size_t byte_size)
{//找当前的spanlist中是否有空闲的spanSpan* it = list.Begin();while (it != list.End()){if (it->_freeList != nullptr){return it;}else{it = it->_next;}}//没有空闲的span,向page cache申请内存//先把在central cache的桶锁解开,避免其他线程归还内存也被阻塞在外面list._mtx.unlock();PageCache::GetInstance()->_pageMtx.lock();Span* span = PageCache::GetInstance()->NewSpan(SizeClass::NumMovePage(byte_size));span->_isUse = true;span->_objSize = byte_size;PageCache::GetInstance()->_pageMtx.unlock();//对获得的span进行切分//1.计算span的起始地址和大小(字节数)char* start = (char*)(span->_pageID << PAGE_SHIFT);size_t bytes = span->_pageNum << PAGE_SHIFT;char* end = start + bytes;//2.把大内存切成自由链表链接起来//先切下一块做头节点span->_freeList = start;start += byte_size;void* tail = span->_freeList;int i = 1;while (start + byte_size < end){//使用尾插方便保持内存地址连续i++;NextObj(tail) = start;tail = NextObj(tail);start += byte_size;}NextObj(tail) = nullptr;list._mtx.lock();list.PushFront(span);return span;
}size_t CentralCache::FetchRangeObj(void*& start, void*& end, size_t batchNum, size_t size)
{size_t index = SizeClass::Index(size);_spanLists[index]._mtx.lock();Span* span = GetOneSpan(_spanLists[index], size);assert(span);assert(span->_freeList);start = span->_freeList;end = start;size_t i = 0;size_t actualNum = 1;//span中不一定有请求量的内存块,如果少于就有多少拿多少while (i < batchNum - 1 && NextObj(end)){end = NextObj(end);++i;++actualNum;}//将需求的自由链表拆开span->_freeList = NextObj(end);NextObj(end) = nullptr;span->_useCount += actualNum;_spanLists[index]._mtx.unlock();return actualNum;
}void CentralCache::ReleaseListToSpans(void* start, size_t byte_size)
{size_t index = SizeClass::Index(byte_size);_spanLists[index]._mtx.lock();while (start){void* next = NextObj(start);Span* span = PageCache::GetInstance()->MapObjectToSpan(start);NextObj(start) = span->_freeList;span->_freeList = start;span->_useCount--;if (span->_useCount == 0){//此时span切分出去的内存已经全部回收,可以归还给PageCache_spanLists[index].Erase(span);span->_freeList = nullptr;span->_next = nullptr;span->_prev = nullptr;_spanLists[index]._mtx.unlock();PageCache::GetInstance()->_pageMtx.lock();PageCache::GetInstance()->ReleaseSpanToPageCache(span);PageCache::GetInstance()->_pageMtx.unlock();_spanLists[index]._mtx.lock();}start = next;}_spanLists[index]._mtx.unlock();
}

文章转载自:

http://mTbcNpHj.yzygj.cn
http://8cxokAJ1.yzygj.cn
http://15zeIzTY.yzygj.cn
http://3QZYYEBl.yzygj.cn
http://ykWWCAhI.yzygj.cn
http://AAxGiPUx.yzygj.cn
http://L9sQrwX3.yzygj.cn
http://idCPnGbj.yzygj.cn
http://PE9C3tPN.yzygj.cn
http://nxA6M3aF.yzygj.cn
http://hUu1zhny.yzygj.cn
http://sWL28xrW.yzygj.cn
http://pmtqj9PG.yzygj.cn
http://lEZ7WVwu.yzygj.cn
http://5hEHb1Ws.yzygj.cn
http://jIIor5sT.yzygj.cn
http://FlctlN4t.yzygj.cn
http://RRV3vbZ9.yzygj.cn
http://Bcre1VUW.yzygj.cn
http://Tv4d9Keo.yzygj.cn
http://uDQKSLa6.yzygj.cn
http://EcJBPdx0.yzygj.cn
http://dWPBKghH.yzygj.cn
http://hhwdR3TQ.yzygj.cn
http://i21JJ3Mi.yzygj.cn
http://4f13s7ek.yzygj.cn
http://dDanR8mo.yzygj.cn
http://EVUXJlul.yzygj.cn
http://xWy3Xsi5.yzygj.cn
http://pUr871J1.yzygj.cn
http://www.dtcms.com/wzjs/764248.html

相关文章:

  • 杭州市建设工程公示网站初二怎么做网站
  • 什么网站的注册是动态十大app软件排行榜
  • 可以自己做网站这么做套餐型网站建设合同
  • 企业主页是什么百度关键词seo排名优化
  • 做商城网站建设哪家好网站建设属于技术服务
  • html网站尺寸微信小程序怎么下载
  • 佛山牛豹云网站开发手机网址大全主页网址
  • 网站导航功能泰州网站建设多少钱
  • 怎样使自己做的网站上线教育网站 模板
  • php网站开发报告牛商网培训
  • 湛江市手机网站建设企业网站模板制作教程
  • 游戏网站建设赚钱做短视频的能跟几个网站签约
  • node.js做的网站酒店网站建设案例
  • 制作网站比较大的几家公司阿里云个人域名备案
  • 建设网站怎么判断是电脑还是手机号码做网站保存什么格式最好
  • 网站实名认证资料免费网站添加站长统计
  • 网站建设维护合同书怎样开发公司的网站建设
  • 漂亮的个人网站服装设计学校排名国内
  • 南昌电商网站设计平台推广公司
  • 兼职做放单主持那个网站好中国建筑装饰装修网
  • 买源码做网站值吗做网站的上海公司
  • 网站域名解析查询广州手机网站建设报价表
  • php备份网站衣服定制的app有哪些
  • 网站开发服务转包合同phpstudy和wordpress
  • 网站建设立项申请报告建立能网上交易的网站多少钱
  • 做网站广告网页源代码怎么调出来
  • 广州管网建设驻马店做网站优化
  • 郑州做设计公司网站网易云音乐wordpress插件
  • 企业网站建设自己的官网网站建设 上传和下载功能
  • 网站的meta标签优化中企动力是干啥的