最近知识梳理不够,那就整理点以前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学习的更多相关文章

  1. iOS copy 和 mutableCopy 学习

    (参考 iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期)的对象部分 关于Copy  有个经典问题”大部分的时候NSString的属性都是copy,那copy与strong的情况下到底 ...

  2. [转帖]学习一下centos7 新地方

    总结的挺好  copy一下 慢慢学习: http://blog.itpub.net/312079/viewspace-2214440/ Centos7 单用户模式 centos7里不再有0-6启动级别 ...

  3. canvas基础学习(四)

    今天逛天猫时,看见优衣库店铺首页有个这个飘雪效果,顿时觉得好酷炫,立马从里面copy代码进行学习. 之前我也做过一些canvas特效,往往在canvas全屏时,canvas下层的div就无法进行dom ...

  4. ant 的详细的入门教程

    Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一.            ...

  5. ANT教程经典

    Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一.            ...

  6. 3d旋转--transform-style: preserve-3d,translate3d(x,y,z),perspective()

    transform-style: preserve-3d,translate3d(x,y,z),perspective() 让其倾斜的核心:加perspective(600px)让其动的核心:rans ...

  7. Oracle第一天

    Oracle第一天 v3.1 整体安排(3天) 第一天:Oracle的安装配置(服务端和客户端),SQL增强(单表查询). 第二天:SQL增强(多表查询.子查询.伪列-分页),数据库对象(表.约束.序 ...

  8. EffectiveC++ 第4章 设计与声明

    我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter4 设计与声明 Designs and Declarat ...

  9. HTML基础总结

    HTML细化知识点总结 1.h1-h6标签 都是标题标签,定义一段话的标题,h1最大,依次递减,h6最小 标题标签的作用:让文本加粗显示 2. 段落标签:p标签 用来显示一段文本(图片),它会忽略源代 ...

  10. laravel 常用知识总结

    看到一篇别人的文章感觉写的不错 就copy过来了 学习源头: https://www.cnblogs.com/yjf512/p/3830750.html aravel是个很强大的PHP框架,它剔除了开 ...

随机推荐

  1. postgres-xl 集体搭建(1)

    安装并编辑脚本 cd /opt/curl -O http://files.postgres-xl.org/postgres-xl95r1beta1.tar.gztar -zxvf postgres-x ...

  2. Fragment和Activity之间通过广播的方式传递数据

    四大组件之间传递数据可以用广播,但是有次面试官说太重了,用eventbus代替.下面的广播传递数据方法仅当学习参考. 1.管理类 /** * 广播管理类:注册广播.注销广播.发送广播 * @autho ...

  3. windows的DOS窗口如何修改大小

    关于这个问题,其实很简单.不知道为什么网上的资料乱遭的.故自己写下来,方便有不明白的童鞋参考. 左键点击左上角的区域会弹出一个菜单,选择属性. 如下图就能轻松的修改窗口的大小了.

  4. windows指令

    &        无条件执行&符号后面的命令: &&      当&&前面的命令成功执行时,执行&&后面的命令,否则不执行: ||   ...

  5. Inno Setup入门(十五)——Inno Setup类参考(1)

    分类: Install Setup 2013-02-02 11:27 536人阅读 评论(0) 收藏 举报 nno setup脚本能够支持许多的类,这些类使得安装程序的功能得到很大的加强,通过对这些类 ...

  6. Sanatorium

    Sanatorium time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  7. HDU5908 Abelian Period 暴力

    题目大意:将一个数组分成长度为k的几个连续区间,如果每个区间内各个元素出现的次数相同,则称k为一个阿贝尔周期,从小到大打印所有阿贝尔周期,数据间加空格. 题目思路:map+暴力 #include< ...

  8. PHP上传图片三个步骤详细分析

    学习PHP时,你可能会遇到PHP上传图片问题,这里将介绍PHP上传图片问题的解决方法,在这里拿出来和大家分享一下.今天我们就开始一起学习PHP上传图片.上传图片原理:首先判断文件类型是否为图片格式,若 ...

  9. ZOJ Problem - 2588 Burning Bridges tarjan算法求割边

    题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍) ...

  10. Linux一些命令

    1.查看系统安装软件 rpm -qa  //(不包括绿色安装的软件程序,也就是直接在安装目录中启动的不包括) rpm -qa |grep gcc 参数解释:q ——询问 a —— 查询全部   l — ...