`
sogotobj
  • 浏览: 653500 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

郁闷的汇编码

阅读更多

我是个编程业余爱好者,虽说是业余,也有近20年了,以前在DOS下编程,计算机速度很慢,内存、硬盘容量也有限,必须对程序代码精益求精,稍大点的程序还得兼顾代码长度和运行速度,否则,你的程序可能跑不起来。
我以前主要用C编程,虽然效率较高,但为了代码长度和速度,关键的代码我喜欢用汇编,相同的算法和流程,ASM和C无论是代码长度和运行速度,都没得比,而且有些特殊的位运算,ASM比C方便多了。在当时dBASE流行的时代(除去系统程序和科技应用及少量的专用商业程序,其它应用几乎清一色dBASE),我的程序还是很受欢迎的(免费的当然受欢迎啦),为此还获得过本系统省级和部级优秀程序奖。新的世纪到来,无论是C还是ASM,几乎有出局的危险,我又喜欢上了DELPHI(DELPHI也快出局了),十年了,C都忘了,而ASM因时不时我喜欢来个BASM函数,所以还没全忘。
前几天,有人在CSDN的汇编语言板块发了个《千分求最快的Base64编码函数》的帖,而刚好我有个Delphi的BASM函数放在BLOG中(参见《Delphi版的Base64转换函数(修改版)》,其中的代码已经是修改过的),自己测试了一下,在我的机器上87MB/s,于是抛砖引玉推荐给了楼主,楼主测试有266MB/s(我的机器是P464位 2.8G,DDR2 667 1G双通道,楼主的是AMD64x2 3600+(2.01G), DDR2 667(334.9MHz))。后来,向楼主推荐代码的越来越多,速度也是越来越快,由几十/s上升到IGM/s以上(楼主测试的),而且有个有趣的现象,相同的算法和流程,C/C++代码普遍比ASM快,在我的印象中,这应该是不可能的,只要汇编码优化到位,速度绝对高于C/C++,于是对我的Base64Encode函数在不改变基本算法的基础上进行了一些简单优化,自己测试164/s,速度比以前提高近一倍,但还是很不理想,没想到楼主的测试结果更气人,居然比我那个没优化的函数还慢,不同的CPU竟然有如此大的悬殊,郁闷!反复优化后的代码速度也不理想,自己测试470MB/s(没改变嵌套循环流程,如果改用顺序执行流程,速度可大大提高,但是我很不喜欢这样的“油条代码”)。

不是C/C++比ASM快吗,于是用C写了2个函数试试,主要代码如下:

staticconstcharbase64table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


unsigned
longBase64_Encode_Byte(void*Source,unsignedlongSourceSize,void*Base64_out)
...{
unsigned
char*pIn=(unsignedchar*)Source;
unsigned
long*pOut=(unsignedlong*)Base64_out;
unsigned
long*pOut_end=pOut+SourceSize/3;
for(;pOut<pOut_end;pOut++,pIn+=3)
...{
*pOut=*(base64table+(pIn[0]>>2))
|*(base64table+(((pIn[0]<<4)|(pIn[1]>>4))&0x3f))<<8
|*(base64table+(((pIn[1]<<2)|(pIn[2]>>6))&0x3f))<<16
|*(base64table+(pIn[2]&0x3f))<<24;
}

Base64_addpaing(pIn,SourceSize
%3,pOut);
return((SourceSize+2)/3)<<2;
}


unsigned
longBase64_Encode_Bit(void*Source,unsignedlongSourceSize,void*Base64_out)
...{
unsigned
char*pIn=(unsignedchar*)Source;
unsigned
long*pOut=(unsignedlong*)Base64_out;
unsigned
long*pOut_end=pOut+SourceSize/3;
unsigned
longdata;
for(;pOut<pOut_end;pOut++,pIn+=3)
...{
data
=*pIn<<16|pIn[1]<<8|pIn[2];
*pOut=*(base64table+(data>>18))
|*(base64table+((data>>12)&0x3f))<<8
|*(base64table+((data>>6)&0x3f))<<16
|*(base64table+((data)&0x3f))<<24;
}

Base64_addpaing(pIn,SourceSize
%3,pOut);
return((SourceSize+2)/3)<<2;
}

Base64_Encode_Byte是按字节拆分后移位重新组合的传统算法,而Base64_Encode_Bit则是先组合成24位二进制内存映像再拆分。在BCB上编译运行,没选择优化的Debug程序都没超过300MB/s,且Base64_Encode_Byte比Base64_Encode_Bit要快一些,打开优化的Release程序都可达550MB/s以上,而此时Base64_Encode_Bit反倒比Base64_Encode_Byte差不多快30MB/s。C代码果真比普通ASM快!我用BCC32 -S -O2 -6编译命令取得Base64_Encode_Bit优化后的ASM代码,几乎没作修改改名为Base64_Encode_ASM编译为Release程序测试,晕!只有470MB/s多。难道BCB给的不是优化ASM码?不得而知,郁闷!
再次反省总结,决定仿效C的ASM码,采用顺序流程(虽然不喜欢,但还是试试)和传统算法重新写了个BASM函数,居然达到710MB/s!相同算法,顺序流程比循环流程快是肯定的,但编程老手们是不愿意为了一点点速度而放弃合理的流程的,确实影响代码的美观和可读性。可是现在也太离谱了,我只要一改为循环,速度就成倍下降,真是郁闷!
好了,总算有可同《千分求最快的Base64编码函数》贴上高手们相媲美的BASM函数了(贴上虽然有1GMB/s左右的函数,但那是拼内存消耗拼出来的,常规算法我这应该算高的了,而且我的机器比他们的慢,估计楼主的测试怎么也有个800-900MB/s吧!),为了放心起见,我没发到贴上,而是发CSDN短信给楼主,让他测试一下,毕竟是他发的贴,以他的测试为准,不一会,结果出来了:“新的Base64_Encode在我的AMDx2 4200+上 427.9MB/s”,注意,是比前面的AMD64x2 3600+(2.01G), DDR2 667(334.9MHz)更快的机器上测试结果!真是郁闷到极点了!!!
汇编码比高级语言兼容性和移植性差,是个不争的事实,但不同的CPU竟然如此大的悬殊,不能不令人悲哀,看来我崇尚的高级语言与ASM组合编程方式应该结束了。
推而广之,高级语言原生代码程序也不可能为每种CPU都编译一个版本,这台机器上跑得很欢的程序到另一台机器上会不会其慢无比?看来说原生代码程序几年后将被JAVA、.NET等中间件托管代码程序取代应该是不假了,难怪有人宣称JAVA的运行速度将超过C/C++,看来也不是不可能,因为中间件托管代码完全可根据不同的机器特性提供最高效率的代码!
以上只是笔者有感而发,有些观点不见得正确,毕竟我只是个业余爱好者,而且年纪很大(多大?你可能猜不着),文化水平也很低(多低,你可能也想不到),同高手们是有相当大的差距的,还希望不吝赐教!

分享到:
评论

相关推荐

    汇编码转机器码万能转换工具.zip

    汇编码转机器码万能转换工具

    汇编码转机器码万能转换工具v1.0绿色免费版

    汇编码转机器码万能转换工具是一款可以将汇编码转成任意机器码的万能汇编码转换器,如果您遇到了多个汇编码需要进行转换,使用这款完全免费的汇编码转机器码万能转换工具一键即可达到目的。 软件特色

    机器码转换汇编

    机器码与汇编语言是计算机科学中的两个基本概念,它们都是与硬件紧密相关的编程语言形式。机器码,也称为机器语言,是计算机硬件能够直接理解和执行的唯一指令集,由二进制数字组成。而汇编语言则是一种介于机器码和...

    可以将汇编码和机器码互转的东西

    可以将汇编码和机器码互转的东西。方便写程序

    汇编转换 机器码转汇编

    在计算机科学领域,汇编语言和机器码是两种基本的编程层次。汇编语言是一种低级编程语言,它与特定的计算机硬件紧密相关,每条指令都对应着计算机硬件能够直接执行的机器码。而机器码是计算机硬件能直接理解和执行的...

    AsmToE汇编机器码转换工具

    《AsmToE汇编机器码转换工具》是一款专为编程者设计的实用软件,它主要功能是将汇编语言程序转换成机器码,并且能够将机器码还原为汇编语言,大大方便了程序员在不同层次上的代码操作。该工具支持最新的指令集,确保...

    64位汇编转机器码

    64位汇编转机器码是编程领域中的一个重要环节,特别是在Windows操作系统环境下,理解这个过程对于深入学习系统级编程和底层开发至关重要。64位汇编语言是针对x64架构设计的,它扩展了传统的32位汇编,以支持更大的...

    86系列汇编指令与机器码对照表_×86-64机器指令_x86_furnitureybl_汇编_

    86系列汇编指令与机器码对照表是一个重要的参考资料,主要针对的是x86架构的处理器,特别是针对8086及其后续的80386、80486和 Pentium等CPU系列。汇编语言是低级编程语言,它的每一个指令直接对应处理器的硬件操作,...

    BCD码转ASCII码的汇编程序

    通过子程序段间调用实现BCD码转ASCII码,经典汇编实例

    汇编转E 汇编转机器码 非常好用的工具

    汇编代码转到机器码工具,支持CE OD格式显示,汇编转E 汇编转机器码 非常好用的工具。 汇编代码转到机器码工具,支持CE OD格式显示,汇编转E 汇编转机器码 非常好用的工具。 汇编代码转到机器码工具,支持CE OD格式...

    单片机51汇编代码与机器码转换对照表

    单片机51汇编代码与机器码转换对照表 单片机51汇编代码与机器码转换对照表是进行反汇编的有效利器。该对照表收录了111条指令,涵盖了数据传送指令、逻辑运算指令、算术运算指令等多种类型。 数据传送指令(30条):...

    汇编机器码转化为汇编指令的软件源码

    标题中的“汇编机器码转化为汇编指令的软件源码”指的是一个程序,该程序能够将计算机执行的二进制机器码转换成可读性更强的汇编语言指令。汇编语言是低级编程语言,它与机器码之间有一一对应的映射关系,而这个软件...

    汇编语言与机器码转换实例

    ### 汇编语言与机器码转换实例解析 #### 一、引言 在计算机科学领域,理解机器码与汇编语言之间的关系至关重要。本文旨在通过深入分析世界计算机编程大赛第一名的作品——“debug64k”(批处理版本),帮助程序员...

    汇编 ASK码显示

    汇编源代码,存入256个ASK码并在屏幕上显示

    51单片机汇编——机器码

    51单片机汇编语言机器码 51单片机汇编语言机器码是指使用助记符编写的单片机汇编语言代码,它可以手工编写单片机汇编,查表手工输入机器码。下面我们将详细解释标题、描述、标签和部分内容中涉及的知识点。 一、...

    汇编代码转成机器码mips-code-to-machine-code

    将汇编代码转换为机器码的过程称为汇编过程,这是一个关键步骤,使得程序员能够用较为易读的形式编写程序,同时保持接近硬件性能的优点。 标题“汇编代码转成机器码mips-code-to-machine-code”指向的就是这个转换...

    汇编实验电话号码查找

    在计算机科学领域,汇编语言是一种低级编程语言,它与机器代码紧密相关,每条指令都对应着特定的机器码。"汇编实验电话号码查找"是一个实践性的项目,旨在帮助学生理解如何使用汇编语言来实现数据的搜索和处理,特别...

    机器码转汇编代码的工具

    机器码转汇编代码的工具·············································

    汇编语言BCD码加法

    在深入探讨汇编语言中的BCD码加法之前,我们首先需要理解BCD(Binary-Coded Decimal)码的基本概念。BCD码是一种将十进制数转换为二进制形式的编码方式,它将每个十进制数字用四位二进制数表示。这种编码方式在处理...

    arm汇编器/用来查看汇编码对应的机器码

    1. **反汇编**:使用反汇编器(如 objdump 或 ndk-stack)将.so文件中的机器码转换回汇编语言,以便于阅读。 2. **分析与修改**:分析汇编代码,找到需要修改的跳转指令,并在汇编语言层面进行修改。 3. **汇编与重...

Global site tag (gtag.js) - Google Analytics