copy-on-write学习
最近知识梳理不够,那就整理点以前blog的东西。
这儿就看COW(copy-on-write),cow技术主要是为了提高程序在单步操作时的系统响应速度而设计的,
它通过将不是立即必要的空间分配,数据复制等耗时操作分摊到后续的某个步骤中,以部分提升性
能。但这种瞬时的性能提升,通常是以部分牺牲总体性能为代价的。
1. copy-on-write的优点
(1)cow能够减少单步操作时由于分配空间及数据复制带来的瞬间延迟
(2)cow能够在一定程度上启动空间优化的作用
2. copy-on-write的应用
(1)cow在g++ std:string中的使用
对于string的实现,不同的程序库有不同的实现方法,g++版的std:string采用的cow技术,
SGI STL string则是采用的eager copy,而Visual c++ 2010中string则是采用的sso,此两
种方法会在附录有简单介绍。
在下面的代码中,证明了g++ std:string中对cow技术的使用:
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std; int main(int argc, char* argv[])
{
string s_str_1 = "hello ymc!";
string s_str_2 = s_str_1; printf("Begin:\n");
printf("s_str_1 At:%x\ns_str_2 At:%x\n", s_str_1.c_str(), s_str_2.c_str()); s_str_2[] = 'y'; printf("\nAfter s_str_2 are modified:\n");
printf("s_str_1 At:%x\ns_str_2 At:%x\n", s_str_1.c_str(), s_str_2.c_str()); return ;
}
以上的代码的运行结果为:
Begin:
s_str_1 At:95a2014
s_str_2 At:95a2014 After s_str_2 are modified:
s_str_1 At:95a2014
s_str_2 At:95a2034
可见,在首次进行赋值时,g++ std:string使用了cow.下面看cow的具体实现。
cow实际是使用计数的方法,使数据在有不同虚拟地址空间的同时,有着相同的物理存储位置,而
具体的的空间分配数据复制则被延迟到数据有个性化需求时。
下面的代码给出了部分cow的实现:
class string
{
public:
string()
:_data(new char[])
{
*_data = '\0';
} string(const char* t_str)
{
if(_data != NULL)
delete _data;
_size = strlen(t_str);
_data = new char[_size + ];
memset(_data, , _size+);
_data++;
strcpy(_data, t_str);
}
//copy-on-write
string(const string& t_str)
{
if(str != *this)
{
_data = str._data;
_size = str._size;
_data[-]++;
}
}
//copy when writing case 1:
char& operator[](unsigned int t_index)
{
if(t_index > _size || _data == NULL)
{
return NULL;
} char* c_tmp = new char[_size + ];
memset(c_tmp, , _size+);
strcpy(c_tmp+, _data);
_data[-]--;
_data = c_tmp; return _data[t_index];
} private:
char* _data;
uint32_t _size;
}
上面的实现中仅仅实现拷贝构造函数及[]操作符部分。一些细节也未在考虑之内,仅专注了cow方面。
一个完整的cow的string的实现还需要增加赋值运算符,+=运算及其它一些成员函数的重载。
引用计数放在-1位置的好处是当字符串增加内容时,不用去调整引用计数存放的位置。
(2)cow在fork进程时的使用
在linux程序中,fork会产生一个与父进程完全相同的子进程,子进程与父进程有着相同的代码段,数
据段,且堆栈也是指向父进程的物理空间的。这样在不考虑子进程中exec的情况,linux在fork时会使
用cow页实现,内核在fork时,并不复制整个进程地址空间,而是让父子进程共享一个拷贝。只有当需
要写入或者修改数据时才会使各个进程拥有自己的拷贝。也就是说,资源的复制操作会等到实际的个性
化需求到来时才会进行。
3.copy-on-write的一些缺陷或可能的陷阱
(1)线程安全有对性能的影响
cow在多线程环境中,需要处理竞态,而其中一引起关键在于:
a.原子操作应尽可能细化,最好只涉及引用计数
b.应该先保证分配复制操作完整后,再高速引用计数
即使是原子操作也会存在一些对性能的影响问题,具体是不同的体系结构在处理lock指令时,往往会锁
住比目标区域更大一些的地址空间,这样会造成一些其它数据的不可操作,影响性能。此外在多cpu情况
下还会出现一些cache-bounce的情况。具体见False sharing.
(2)可能的陷阱
主要体现在将string作为返回值处理时,注意后面的引用,特别是返回值声明为静态的情况。
附录:
主要是string的eager copy,cow,sso的三种实现。
上图引用自 https://github.com/downloads/chenshuo/documents/CppPractice.pdf
以上三种方式,eager copy的实现最简,其次sso,最麻烦的是cwo。不过也可以尝试将三种方式结合
起来设计string,根据字符串长度在处理时使用不同的处理原则,调整时配置可使性能达最优。
copy-on-write学习的更多相关文章
- iOS copy 和 mutableCopy 学习
(参考 iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期)的对象部分 关于Copy 有个经典问题”大部分的时候NSString的属性都是copy,那copy与strong的情况下到底 ...
- [转帖]学习一下centos7 新地方
总结的挺好 copy一下 慢慢学习: http://blog.itpub.net/312079/viewspace-2214440/ Centos7 单用户模式 centos7里不再有0-6启动级别 ...
- canvas基础学习(四)
今天逛天猫时,看见优衣库店铺首页有个这个飘雪效果,顿时觉得好酷炫,立马从里面copy代码进行学习. 之前我也做过一些canvas特效,往往在canvas全屏时,canvas下层的div就无法进行dom ...
- ant 的详细的入门教程
Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一. ...
- ANT教程经典
Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一. ...
- 3d旋转--transform-style: preserve-3d,translate3d(x,y,z),perspective()
transform-style: preserve-3d,translate3d(x,y,z),perspective() 让其倾斜的核心:加perspective(600px)让其动的核心:rans ...
- Oracle第一天
Oracle第一天 v3.1 整体安排(3天) 第一天:Oracle的安装配置(服务端和客户端),SQL增强(单表查询). 第二天:SQL增强(多表查询.子查询.伪列-分页),数据库对象(表.约束.序 ...
- EffectiveC++ 第4章 设计与声明
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter4 设计与声明 Designs and Declarat ...
- HTML基础总结
HTML细化知识点总结 1.h1-h6标签 都是标题标签,定义一段话的标题,h1最大,依次递减,h6最小 标题标签的作用:让文本加粗显示 2. 段落标签:p标签 用来显示一段文本(图片),它会忽略源代 ...
- laravel 常用知识总结
看到一篇别人的文章感觉写的不错 就copy过来了 学习源头: https://www.cnblogs.com/yjf512/p/3830750.html aravel是个很强大的PHP框架,它剔除了开 ...
随机推荐
- docker Swarm 集群发现
Node 发现 $swarm manage --discovery dockerhost01:,dockerhost02:,dockerhost03: -H= 文件发现 $swarm manage - ...
- easyui 动态渲染
$.parser.parse 这个 $("div[data-easyuisrc]").html(function () { var url = $(this).attr(&qu ...
- QML Flipable、Flickable和状态与动画 上篇
本文介绍的是QML Flipable.Flickable和状态与动画,我们以前接触过QML组件,和一些QML相关的内容,那么本文介绍的内容就很明了了.先来看内容. AD:51CTO 网+ 第十二期沙龙 ...
- 在ASP.Net中"../" "./" "~/"表示的意思
"../" 相对当前(根据不同的语境,当前是不同的)的上一级目录"./" 就是当前目录 "~/" 当前项目的根路径,只在服务器端有效.
- Tree Restoring
Tree Restoring Time limit : 2sec / Memory limit : 256MB Score : 700 points Problem Statement Aoki lo ...
- WPF InkCanvas 画图 基础使用教程
大家好,由于很多原因,我有很长一段时间没有在 CSDN 上分享我的学习成果了,如今终于可以回归分享之路了. 之前在做一个项目的时候,想在一个区域里绘制自己的图形,于是上网搜索资料,无意中找到了 Ink ...
- 直接在script里面换样式IE6,7,8不兼容
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- RMQ 详解
RMQ(Range Minimum/Maximum Query)问题:RMQ问题是给定一个区间,求这个区间中的最大或最小值的问题 RMQ采用动态规划的思想来求解:(st算法:Square Table) ...
- 3--OC -- 点语法
3.OC -- 点语法 1.方法名 // 冒号也是属于方法名的一部分 - (void)setAge:(int)age; // 方法名是 setAge: - (void)setAge; // 方法名是 ...
- TweenMax说明
TweenMax 采用了与它的兄弟相似的易于学习的语法结构.实事上,因为它扩展自它们,TweenMax 可以做任何 TweenLite 和/或者 TweenFilterLite 能做的事,还加上了更多 ...