【转载】使用C#进行系统编程
原文:使用C#进行系统编程
虽然对于系统编程(System programming)的定义很模糊,不过可以将其描述为在比特、字节、指令,或CPU周期层面所进行的思考。系统编程这个概念也暗含了对性能和可靠性的需求。Microsoft技术总监Joe Duffy在 QCon New York 活动中介绍了使用C#进行系统编程的战略,同时他还谈到了这其中的一些陷阱以及缓解方法。
Joe的演讲中很多内容来自一个名为Midori的研究项目。该项目意在使用C#从零开始打造一个操作系统,这也让我们对编译器的结构和有关高性能代码的新战略有了全新认识。
使用托管语言(Managed language)构建操作系统使得我们能够在内存层面上运用C#中的安全功能。这样做可以避免由于缓冲区溢出或格式字符串(Format string)弱点而针对内存进行的代码注入攻击,因为此时可以由运行时负责边界检查(Bound checking)和类型安全(Type safety)。
代码的生成
代码可以通过预先(Ahead of time,Aot)或即时(Just in time,Jit)的方式编译。Jit的优势在于编译速度更快,但Aot可以获得更好的机器代码,因为编译器可以对代码执行更多优化。
原生语言编译器实现的很多优化原本是托管语言所不具备的。一般原因通常在于,通过Jit编译器实现这些优化通常可能需要极大的运算量或过于复杂。正是这些问题导致C#在紧密、高效的底层代码生成方面口碑不佳。最近通过RyuJit实现了下列这些优化:
- Inlining(使用所调用函数的主体取代函数调用点)
- Flowgraph和Loop分析
- 静态单一指派(SSA)和全局值编号
- 通用子表达式消元(Common subexpression elimination)
- 复制/常量传播(Copy/constant propagation)
- 无用代码删除
- 范围分析
- 非虚拟化(Devirtualization)
- 循环不变量代码提升(Loop invariant code hoisting)
- SIMD和向量化
- 通用共享(Generic sharing)
- 堆栈分配(正在开发中)
垃圾回收
.NET中的垃圾回收已发展到第三代。一些数据程序分析师需要将自己过半的时间用于垃圾回收,而无法用在更有价值的工作中。
改善性能的方法之一是使用Struct,Struct可改善下列领域的性能问题:
- 降低GC压力,因为Struct是针对堆栈分配的。
- 提高内存局部性(Memory locality),改善缓存命中率。
- 整体减少对内存的使用,避免32-64位应用程序中对象的8-16字节开销。
关于Struct有个问题需要注意:在复制超出某一大小的Struct时可能导致Memcpy。为了优化性能,应确保Struct尽可能小,不要超过32/64字节。
C# 7的一些功能使得通过Struct进行底层优化的过程变得更容易。C# 7的元数组(Tuple)是Struct,而非老版本中的System.Tuple<>,后者现已成为对象。引用返回则是Struct的另一个特性,可以无需复制直接通过函数返回Struct。
错误处理
可恢复的错误总会存在例外,然而很多错误都是不可恢复的。诸如无效转换、栈溢出以及空引用等错误实际上属于Bug。但I/O故障和验证错误是可以预见并从中恢复的。
这种错误恢复催生了Fail fast策略。 Fail fast 是一种包含在.NET中的机制,这种机制下诸如StackOverflow等例外可能会绕过异常处理程序导致进程崩溃。该策略使得查找此类错误的过程变得更简单,因为此时例外已经无法被过度的通用异常处理程序所处理。Midori团队发现他们的可恢复错误(例外)与Bug(Fail fast)已经达到了1:10的比例。
详细信息请参阅Joe的博客,他在博客上写了 很多有关Midori的文章 。他的 演讲演示文稿 也已经发布到网上。
查看英文原文: Systems Programming in C#
【转载】使用C#进行系统编程的更多相关文章
- Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)
在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...
- Linux系统编程【3.1】——编写ls命令
ls命令简介 老规矩,直接在终端输入:man ls (有关于man命令的简介可以参考笔者前期博客:Linux系统编程[1]--编写more命令) 可以看到,ls命令的作用是显示目录中的文件名,它带有可 ...
- Linux系统编程【1】——编写more命令
背景介绍 笔者知识背景 笔者接触Linux快一年了.理论知识方面:学习了操作系统基础知识,了解进程调度.内存分配.文件管理.磁盘I/O这些基本的概念. 实操方面:会使用Linux简单命令,在嵌入式系统 ...
- Linux系统编程【2】——编写who命令
学到的知识点 通过实现who命令,学到了: 1.使用man命令寻找相关信息 2.基于文件编程 3.体会到c库函数与系统调用的不同 4.加深对缓冲技术的理解 who命令的作用 who命令的使用 在控制终 ...
- Linux系统编程【3.2】——ls命令优化版和ls -l实现
前情提要 在笔者的上一篇博客Linux系统编程[3.1]--编写ls命令中,实现了初级版的ls命令,但是与原版ls命令相比,还存在着显示格式和无颜色标记的不同.经过笔者近两天的学习,基本解决了这两个问 ...
- linux下系统编程C环境搭建
一.系统安装 我使用的是VMware8下的ubuntu12.04,这是培训老师说的,12.04相对来说,比较新,而且是5年长期支持版,不容易过时.对于系统的安装,我不想说很多,只是希望大家主义这几点: ...
- Linux系统编程温故知新系列 --- 01
1.大端法与小端法 大端法:按照从最高有效字节到最低有效字节的顺序存储,称为大端法 小端法:按照从最低有效字节到最高有效字节的顺序存储,称为小端法 网际协议使用大端字节序来传送TCP分节中的多字节整数 ...
- linux系统编程之错误处理
在linux系统编程中,当系统调用出现错误时,有一个整型变量会被设置,这个整型变量就是errno,这个变量的定义在/usr/include/errno.h文件中 #ifndef _ERRNO_H /* ...
- LINUX系统编程 由REDIS的持久化机制联想到的子进程退出的相关问题
19:22:01 2014-08-27 引言: 以前对wait waitpid 以及exit这几个函数只是大致上了解,但是看REDIS的AOF和RDB 2种持久化时 均要处理子进程运行完成退出和父进程 ...
随机推荐
- 本周PSP+历年作品评论
本周PSP 类别 内容 开始时间 结束时间 间断时间 净时间(min) 9月11号 看书 构建之法 19:00 21:00 14 106 9月12号 写程序 词频统计多需求版 8:00 14:23 3 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON BinThreshold
zw版[转发·台湾nvp系列Delphi例程]HALCON BinThreshold unit Unit1;interfaceuses Windows, Messages, SysUtils, Var ...
- 基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现
概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有更好的实用性. 架构 我们采用的是MVC5(本文中介绍的方法对于MVC4也是 ...
- javascript中的this与prototype,原型理解
JavaScript 函数调用 JavaScript 函数有 4 种调用方式. 每种方式的不同方式在于 this 的初始化. this 关键字 一般而言,在Javascript中,this指向函数执行 ...
- selenium+phantomJS学习使用记录
背景知识: phantomjs是一个基于webkit的没有界面的浏览器,所以运行起来比完整的浏览器要高效. selenium是一个测试web应用的工具,目前是2.42.1版本,和1版的区别在于2.0+ ...
- PS4 的下载速度问题
折腾了好久了 AC68u路由自启动修改 hosts 问题,打算FQ另外改善 ps4 下载速度太慢问题. 后来看到几个dns, 直接修改后就速度超快,也不用在路由中添加了, 直接在 ps4 中网络设置中 ...
- Jquery 插件库
http://www.jq22.com/ 日期: http://laydate.layui.com/
- Sublime Text 3 常用插件以及安装方法
安装Sublime Text 3插件的方法: 一.直接安装 安装Sublime text 2插件很方便,可以直接下载安装包解压缩到Packages目录(菜单->preferences->p ...
- minio-dotnet --云存储服务
inio是一家成立于2014年的生产开源云存储产品的新兴创业公司.这家创业公司是其创始人继Gluester之后的又一杰作,Gluester公司已经在2011年被Red Hat公司以1.36亿美元的价格 ...
- oracle sqlloader 用法
向oracle中导入*.csv文件 1.什么是*.csv,如何得到? 里面存放的是数据表.每行代表数据库表格的一行, 每行中,每两个数据中间由逗号","分割. *.csv可以通 ...