随笔- 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. Swift的笔记和参考

    原文:Swift的笔记和参考 好久没来了,趁着新语言Swift发布,继续钻研中! Create Class 创建类 (多态效果) // Create Class 创建类 class MyClass { ...

  2. MyReport报表引擎2.7.6.7新功能

    新增二维码控件PDF417 设计器新增数据选项卡,可以拖放字段进行绑定   相关链接 MyReport演示.产品站点 相关文章 MyReport专栏

  3. 客户端程序通过TCP通信传送"小文件"到服务器

    客户端程序通过TCP通信传送"小文件"到服务器 [c#源码分享]客户端程序通过TCP通信传送"小文件"到服务器 源码  (不包含通信框架源码,通信框架源码请另行 ...

  4. Quartz使用-入门使用(java定时任务实现)

    注:这里使用的是Quartz1.6.5版本号(包:quartz-1.6.5.jar) //測试main函数 //QuartzTest.java package quartzPackage; impor ...

  5. Linux C 多线程

    原文:Linux C 多线程 linux下C语言多线程编程 #include <pthread.h> #include <stdio.h> #include <sys/t ...

  6. MySQL 一般查询日志(General Query Log)

    与大多数关系型数据库,日志文件是MySQL数据库的一个重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志.慢查询日志,等等. 这些日志能够帮助我们定位mysqld ...

  7. 把VBScript的函数迁移到C#.NET

    原文:把VBScript的函数迁移到C#.NET VBScript 5.6 Functions C# code Abs System.Math.Abs Array New Object() { } A ...

  8. Asp.net vNext 学习1

    Asp.net vNext 学习之路(一) 概述 asp.net vNext 也叫 asp.net 5.0,意思是微软推出的下一个版本的asp.net.可以说是微软对asp.net的一个比较重大的重新 ...

  9. HDOJ 4416 Good Article Good sentence

    题解转自:http://blog.csdn.net/dyx404514/article/details/8807440 2012杭州网络赛的一道题,后缀数组后缀自己主动机都行吧. 题目大意:给一个字符 ...

  10. 增加 Java 有几个好习惯表现

    以下是一些参考网络资源中的摘要Java编程在一些地方尽可能做. 1. 尝试使用单个例如在合适的场合 使用单例可以减轻负荷的负担,缩短加载时间.提高装载效率,但并不是所有的地方都适合一个案例.简单的说, ...