随笔- 5  文章- 0  评论- 10 

LLVM小结

 

如果说gcc是FSF的传奇,llvm就是Chris Lattner的小清新。当然啦,想具体看看这位四处游山玩水还GPA 4.0的大神和他的LLVM编译链还有他与苹果之间的故事的读者可以移步http://news.cnblogs.com/n/127343/。另外,据悉,FreeBSD自10.0开始将会完全采用llvm编译链编译,而之前的版本,与Linux一样,都是采用的gcc编译的。

以上,就算是“拉大旗扯虎皮”,既是给llvm做个简介,也是让大家知道本篇博文还是说的是比较“有用”的东西,而不是什么虚无飘渺的东西。

llvm在编译链中的环节其实是属于后端,前端可以采用gcc或者clang(从某些编译课程来看,用yacc和bison写的前端也行)。gcc想必大家都很熟悉,我也就不再赘述。clang则是专门为llvm定制的前端,据说当初开发它的一个很重要的因素就是gcc和IDE配合得不太好,而且gcc模块之间写得比较混杂,难以修改。作为前端,虽然我没有使用过配合clang的IDE(Apple developer能使用到的XCode算一个,不过我还没真正用过),但确实,在终端下调试的时候clang给出的输出比gcc的要好理解得多。不过clang是名副其实的CLang,只支持C/Obj-C/C++这三种语言;而gcc当然是无所不包无所不能的了。这里我上个C程序的例子吧(如果觉得不过瘾,你可以自行尝试C++,据说C++的类模板最能体现这两者的区别,也可以直接去http://blog.llvm.org/2010/04/amazing-feats-of-clang-error-recovery.html):

1 #include <stdio.h>
2
3 int main(){
4 return 1? 2 3
5 }

我们来看看clang和gcc给出的出错信息分别是什么(为了证实确实是这段程序,我先cat了它):

首先,其实gcc没有给全出错信息,如果你只照gcc的输出在第4行14列添加了冒号,那么你再次编译的时候它还会告诉你这一行的末尾缺分号;而clang不仅给全了错误而且每个错误都是出错信息一行,源代码一行,建议一行(note也是这样的),并且输出有色彩分别。笔者的gcc版本是4.7.3,clang版本是3.2-1,都是Ubuntu 13.04下最新的(顺带插一句:不知道为什么llvm 3.3已经发布很久了,Ubuntu还没有正式采用)。我觉得前端有一个很重要的功能就是报错,clang做得很好,至少这点比gcc做得好。苹果的产品在“看得见”的地方一向都做得很好,clang也是这样的。

编译器的前端,不仅要能生成AST,而且如果源代码有语法错误或者警告(虽然程序猿貌似都忽略警告,但实际上有的时候警告还是很有用的)要应当能给我们很好的指出,毕竟我们是人不是机器,要人性化一点;另外,后端又要能够在前端分析出的AST为程序做出极致的优化,当然,我不是说程序优化就靠编译器了,程序猿本身就应当编写出好的代码,但是编译器确实应当负责优化程序。llvm和gcc到底谁优化得更好,大家说法不一,给出的数据差距也很大,但是呢,不过呢,“LLVM has been awarded the 2012 ACM Software System Award!”,估计肯定是不会差的了。除了各种天花乱坠的数据外(如果非要看的话,我还是给个早年的数据吧:http://llvm.org/pubs/2007-07-25-LLVM-2.0-and-Beyond.pdf),毕竟程序最终是要给用户用的,毕竟用户体验才是最重要的,所以我们直接比较产品。举个栗子:LLVMpipe,这是一个类似于即时编译或者说在线编译的东西,它将OpenGL的代码(本来是抛给GPU的)编译为CPU可执行的代码并交由CPU执行。这个东西被很多支持老旧电脑的Linux发行版所采用,所以想来效率也不会太差。当然,效率高不高和运行快不快其实并不等价,因为运行快不快和具体的硬件环境还是有很大关系的。

说到编译优化,llvm似乎还有一个奇怪的优化方法:llvm(low level virtual machine)本身就是一种抽象的、虚拟的计算机架构,其特性介于RISC和CISC之间,llvm会先将代码编译为llvm架构的字节码(这里还是说说数据吧,从其官方数据来看,生成的字节码略多于x86的目标代码而少于SPARC的目标代码),然后可以对字节码进行JIT优化然后再翻译为目标架构的二进制代码。另外,llvm实际上采用的是一种全生命周期(lifelong)的优化策略(虽然还是很偏重静态优化),最直接的体现就是比起gcc能做到的 -O3,llvm可以做到 -O4,而且 -O4采用的是LLVMgold.so所提供的运行时库。llvm本身的设计思想就是希望做到编译时、链接时、运行时、空闲时的全方位优化。关于这些优化,在llvm官网可以找到,请移步http://llvm.org/pubs/2004-01-30-CGO-LLVM.html

最后来说一下llvm和gcc的兼容性,我前面只是说了llvm的后端兼容gcc的前端生成的AST,其实llvm对gcc的兼容性是很高的,我现在系统的环境变量CC设置的就是clang,我编译了很多工程都不用改Makefile就可以成功编译,不过很多工程里只是采用的 -O2,让我略不爽,所以我就手动将之改为 -O4,当然也就需要修改一下CFLAGS和LDFLAGS,为之加上llvm-config的输出。llvm本身在脚本上就设计为和gcc的兼容,所以改换编译链十分容易。

开源库CImg 数据格式存储之二(RGB 顺序)

 

在上一篇博客中已经初步说明了GDI和CImg数据的存储格式感谢博友 Imageshop 评论说明

CImg的说明文档中已有详细说明(详见上篇博客说明)

CImg的数据格式确实是RRRGGGBBB顺序存储的已经毫无疑问,但是其参考手册中对其他GDI

的数据格式说明是略有瑕疵,参考手册说其他GDI的数据格式是RGBRGBRGB,其实则不是经过验证

bmp类型的数据格式应该是BGRBGRBGR 下面用code验证

说明:使用MFC 同时用CImage和CImg加载同一幅图片

void ImageIO::loadImage(const BiCImg & image, T*& pImagePlane,int& width,int& height,int& nchannels)
{
// get the image information width=image.width();
height=image.height();
nchannels=3;
int rgb_leng=width*height;
pImagePlane=new T[width*height*nchannels]; // check whether the type is float point
bool IsFloat=false;
if(typeid(T)==typeid(double) || typeid(T)==typeid(float) || typeid(T)==typeid(long double))
IsFloat=true; const unsigned char* plinebuffer;
plinebuffer=image.data(0,0);
for(int i=0;i<height;i++)
{
//plinebuffer=image.scanLine(i);
for(int j=0;j<width;j++)
{ pImagePlane[(i*width+j)*3]=plinebuffer[i*width+j+2*rgb_leng];//RGB b
pImagePlane[(i*width+j)*3+1]=plinebuffer[i*width+j+rgb_leng];//RGB g
pImagePlane[(i*width+j)*3+2]=plinebuffer[i*width+j];//RGB r }
}
}

上述为正确的顺序,若改为如下代码

pImagePlane[(i*width+j)*3]=plinebuffer[i*width+j];//RGB r

pImagePlane[(i*width+j)*3+1]=plinebuffer[i*width+j+rgb_leng];//RGB g

           pImagePlane[(i*width+j)*3+2]=plinebuffer[i*width+j+2*rgb_leng];//RGB b

实验效果如下图

右图为原始图片,明显左图的蓝色部分取代了原始图片的红色应该是BGR缺写成了RGB

 
 
 
 
 

LLVM小结的更多相关文章

  1. Objective-C 里面的类对象复用小结

    OC 提供了单继承 (Inheritance), Category, Extension, Protocol 这几种基本的类与对象层面的复用机制,作一小结. 在这几个机制中,继承提供了纵向的复用,可以 ...

  2. TVM量化小结手册

    TVM量化小结手册 文章目录 Offical References TVM quantization roadmap INT8 quantization proposal Quantization S ...

  3. 从零开始编写自己的C#框架(26)——小结

    一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...

  4. Python自然语言处理工具小结

    Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...

  5. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  6. iOS--->微信支付小结

    iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...

  7. iOS 之UITextFiled/UITextView小结

    一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...

  8. K近邻法(KNN)原理小结

    K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...

  9. scikit-learn随机森林调参小结

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...

随机推荐

  1. IOS新手教程(二)-控制流

    int main(){ //2.控制流 //2.1 if语句 //1. if(expression){ } //2. if(expression){ }else{ } //3.能够有0个或是多个els ...

  2. 教你一步一步部署.net免费空间OpenShift系列之三------上传ASP.net程序

    接上回书,创建应用后,我们如何将自己的ASP.Net部署到应用空间呢,这里用WinSCP的SFTP协议进行上传和下载 上传ASP.net程序 下载WinSCP,并打开PuTTYGen 点击Genera ...

  3. 【百度地图API】今日小年大进步,齐头共进贺佳节——API优化升级上线,不再增加内存消耗

    原文:[百度地图API]今日小年大进步,齐头共进贺佳节--API优化升级上线,不再增加内存消耗 任务描述: 今天是2011年01月26日,小年夜.百度地图API在小年夜献给广大API爱好者一份给力的礼 ...

  4. 第1章2节《MonkeyRunner源码剖析》概述:边界(原创)

    天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...

  5. 利用docker搭建yii2 详细步骤

    定位镜像 在hub.docker.com 搜索yii2,并且最后定位到 https://hub.docker.com/r/codemix/yii2-base/codemix/yii2-base 然后在 ...

  6. C# 关闭子线程的方法

    将子线程设定为IsBackGroud = true,程序关闭则自动死亡. 暴力手段:System.Environment.Exit(0).关闭时直接x掉所有线程. 子线程自行结束:子线程中自己判断.可 ...

  7. Gimp教程:制作彩色的网站横幅

    效果图: Step1.新建900x200的透明图层 Step2.点选画笔工具,在左下方的设置界面进行如下: 设置画笔,动态,颜色,勾选应用抖动,然后试着在图层上画一画,调节一下画笔大小,相信你能作出如 ...

  8. VS2015安装

    VS2015安装 Secondary Installer Setup Failed求解决方案 看到微软最近的一系列变化,着实让我等兴奋不已.VS2015下载地址就不说了.先来记录一下微软的几个变化吧. ...

  9. 在项目管理工具Redmine中使用SubVersion进行版本管理

    原文:在项目管理工具Redmine中使用SubVersion进行版本管理 在项目管理工具Redmine中使用SubVersion进行版本管理 分类: Redmine2009-06-01 10:11 5 ...

  10. iOS_1_加法器

    : BeyondViewController.h // // BeyondViewController.h // 01_calc // // Created by beyond on 14-7-20. ...