优化,通常涉及软件算法与硬件体系结构等方面的深层知识。在通常的情况下,编译器会为我们生成一个比较理想的程序,因此,除非特别需要,在进行手工优化之前,必须要确定编译器生成的代码是否真的没有经过优化,以及能够进行何种程度的优化。并且,最重要的一条是:不要凭感觉和经验行事,要对优化前后各个情况下的运行结果进行统计和比较分析。因为,经常地,有时千辛万苦,绞尽脑汁优化后,可能效率不升反降,代码运行的更慢,正应了那句老话:一个锅盖扣不到所有的锅上。

就实际而言,优化是个复杂的工作,感觉和经验并不总是靠谱。由于硬件结构的复杂性,特别是X86,深思熟虑,有针对性的进行优化才能取得较好的结果。构造一个与目标环境一致的测试环境,在这个环境下进行详细的运行测试,仔细的收集运行数据,并进行统计和比较,然后在分析结果的指引下,对程序进行有针对性的优化,以数据说话,才可以得到比较好的结果。

让我们稍稍的深入硬件结构,针对硬件的特性,来一个优化的例子。

大家都知道CPU的片内缓存(Cache)。也知道CPU对数据进行操作是沿-内存->缓存->内存-的路径进行,更认为我们比机器和编译程序更加了解自己的代码和目标数据的特性,所以问题来了:如果我们能够在CPU从内存取数据之前提前将数据加载到缓存中,人为的干预这个过程,减少CPU访问缓冲不命中后不得不访问内存的情况,是不是能够提高性能呢?貌似可行。那么,什么样的内存操作会和缓存有较大的关联?首先想到的肯定是内存拷贝操作。这个操作通常都是用memcpy来完成。这个函数的速度已经很快了,它的大多数实现形式都是基于REP MOVSD循环移动命令的,该命令在每次循环中拷贝4个字节的数据。自然而然地,我们会产生对它进行优化的想法。至少主观上,可能认为该函数是为通用情况设计的,不一定在所有情况下都能发挥出CPU的潜力。那么,究竟还有没有优化的可能呢?值得一试,即使失败了,也可得获得有益的经验。

我们知道,通过缓存预取指令,可以由我们来决定缓存应该加载什么样的内容。在这里,先看看下面摘自itwiki的一段关于CPU缓存的说明:

AMD(略)

Intel

自P4时代开始,Intel开始采用全新的“数据代码指令追踪缓存”设计。基于这种架构的一级数据缓存不再存储实际的数据,而是存储这些数据在二级缓存中的指令代码(即数据在二级缓存中存储的起始地址)。假设处理器需要读取“INTEL P4 IS GOOD”这一串数据(不记空格),那么所有数据将被存储在二级缓存中,而一级数据代码指令追踪缓存需要存储的仅仅是上述数据的起始地址。由于一级数据缓存不再存储实际数据,因此“数据代码指令追踪缓存”设计能够极大地降CPU对一级数据缓存容量的要求,降低处理器的生产难度。但这种设计的弊端在于数据读取效率较“实数据读写缓存设计”低,而且对二级缓存容量的依赖性非常大。


已注销
6 声望2 粉丝

A babysitter.