我不是在谈论算法的东西(例如使用quicksort而不是bubblesort),而我不是在讨论像循环展开之类的简单事情.
我在谈论硬核的东西.像Tiny Teensy ELF,Mel的故事 ; 几乎所有在demoscene,等等.
Ski*_*izz 28
我曾经写过一个暴力RC5密钥搜索,一次处理两个密钥,第一个密钥使用整数流水线,第二个密钥使用SSE流水线,两个密钥在指令级交错.然后将其与管理程序结合使用,该程序在系统中的每个核心上运行代码实例.总的来说,代码运行速度比原始C版本快25倍.
sin*_*e j 10
在DOS的早期,当我们使用软盘进行所有数据传输时,也存在病毒.病毒感染不同计算机的一种常见方法是将病毒引导程序复制到插入的floppydisc的引导程序中.当用户将floppydisc插入另一台计算机并重新启动而不记得移除软盘时,病毒就会运行并感染硬盘启动器,从而永久感染主机PC.我被感染的一种特殊的令人讨厌的病毒被称为"Form",为了对抗这一点,我编写了一个具有以下功能的自定义软盘bootsector:
这是在bootsector的程序空间中完成的,大约440字节:)
我的伙伴最大的问题是显示非常神秘的消息,因为我需要所有代码空间.它就像"FFVD RM?",意思是"检测到FindForm病毒,删除?"
我很满意这段代码.优化是程序大小,而不是速度.装配中有两种完全不同的优化.
我最喜欢的是通过整数运算的浮点反平方根.这是关于如何存储浮点值并且可以更快执行的一个很酷的小问题(即使执行1 /结果比股票标准平方根函数更快)或者产生比标准方法更准确的结果.
在c/c ++中,代码是:(来自维基百科)
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1); // Now this is what you call a real magic number
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
快速背景: DNA核苷酸三联体(A,C,G和T)编码氨基酸,这些氨基酸与蛋白质结合,蛋白质是大多数生物的组成部分.
通常,每种不同的蛋白质需要单独的DNA三联体序列(其"基因")来编码其氨基酸 - 因此例如长度为30,40和50的3种蛋白质总共需要90 + 120 + 150 = 360个核苷酸.然而,在病毒中,空间是非常宝贵的 - 因此有些病毒会重叠不同基因的DNA序列,因为有6个可能的"阅读框架"用于DNA到蛋白质的翻译(即从一个位置开始)可以被3整除;从3除以余数1的位置;或从3除以余数2的位置;再次相同,但反过来读取序列.)
为了比较:尝试编写一个x86汇编语言程序,其中300字节函数doFoo()从偏移量0x1000开始......另一个200字节函数doBar()从偏移量0x1001开始!(我为这次比赛提出一个名字:你比乙肝更聪明吗?)
这是硬核空间优化!
更新:链接到更多信息:
几年前,我用65816汇编语言为Apple IIgs写了一个基于磁贴的游戏引擎.这是一台相当慢的机器,"在金属上"编程是哄骗可接受性能的虚拟要求.
为了快速更新图形屏幕,必须将堆栈映射到屏幕,以便使用一些特殊指令,允许用户仅在5个机器周期内更新4个屏幕像素.这并不是特别奇妙,在IIgs Tech Note#70中有详细描述.硬核位是我必须组织代码以使其足够灵活以成为通用库同时仍保持最大速度的方式.
我将图形屏幕分解为扫描线并创建了一个246字节的代码缓冲区来插入专门的65816操作码.需要246个字节,因为图形屏幕的每条扫描线宽80字,每端需要1个附加字以便平滑滚动.推送有效地址(PEA)指令占用3个字节,因此3*(80 + 1 + 1)= 246个字节.
通过跳转到对应于屏幕右边缘的246字节代码缓冲区内的地址并将BRanch Always(BRA)指令修补到紧随最左边单词后面的单词的代码中来呈现图形屏幕.BRA指令将带符号的8位偏移量作为其参数,因此它几乎没有跳出代码缓冲区的范围.
即便这样也不是太困难,但真正的硬核优化就在这里.我的图形引擎实际上支持两个独立的背景图层和动画图块,使用不同的3字节代码序列,具体取决于模式:
关键限制是65816寄存器(X和Y)都用于引用数据,不能修改.此外,直接页面寄存器(D)是基于第二背景的原点设置的,并且不能改变; 数据库寄存器设置为保存第二背景的像素数据的数据库,不能更改; 堆栈指针(S)映射到图形屏幕,因此不可能跳转到子程序并返回.
鉴于这些限制,我需要快速处理即将被推入堆栈的单词混合的情况,即一半来自背景1,一半来自后台2.我的解决方案是交换内存以获得速度.因为所有正常寄存器都在使用中,所以我只能使用程序计数器(PC)寄存器.我的解决方案如下:
这是实际的代码片段
code_buff: PEA $0000 ; rightmost word (16-bits = 4 pixels)
PEA $0000 ; background 1
PEA $0000 ; background 1
PEA $0000 ; background 1
LDA (72),y ; background 2
PHA
LDA (70),y ; background 2
PHA
JMP word_68 ; mix the data
word_68_rtn: PEA $0000 ; more background 1
...
PEA $0000
BRA *+40 ; patched exit code
...
word_68: LDA (68),y ; load data for background 2
AND #$00FF ; mask
ORA #$AB00 ; blend with data from background 1
PHA
JMP word_68_rtn ; jump back
word_66: LDA (66),y
...
Run Code Online (Sandbox Code Playgroud)
最终结果是接近最佳的阻击器,具有最小的开销,并且在具有1 MB/s存储器总线的2.5MHz CPU上以320x200的速度输出超过15帧/秒.
迈克尔·阿布拉什(Michael Abrash)的" 汇编语言之禅 "(Zen of Assembly Language)有一些漂亮的东西,不过我承认我不记得我头脑中的细节.
实际上,似乎Abrash所写的一切都有一些漂亮的优化内容.
| 归档时间: |
|
| 查看次数: |
2120 次 |
| 最近记录: |