您现在的位置是:主页 > news > 网站做链接的意义是什么/关键词优化快排
网站做链接的意义是什么/关键词优化快排
admin2025/6/28 18:08:15【news】
简介网站做链接的意义是什么,关键词优化快排,山东德州网站建设哪家最好,中国建设银行网站的发展利用CPU缓存 计算机有随机存取存储器RAM(译注:即我们常说的内存),但有更快形式的存储器。如果你希望你的应用程序的快速运行,你需要知道这些其他的存储器。今天的文章中讨论了它们,并给出了两个AS3例子&am…
利用CPU缓存
RAM的确很快,但只是与硬盘,固态硬盘,光盘,互联网等等与比较时。RAM与CPU内置的高速缓存相比,它并不快。你可能已经听说过他们,CPU高速缓存的级别分别称为:L1,L2和L3。
CPU高速缓存用来存储小块的RAM内容。当RAM被请求时,可以使用更快的高速缓存,而不是...但只有当所请求的RAM是在高速缓存中的。这就是所谓的高速缓存“命中”。如果高速缓存“miss”,CPU需要从较慢的RAM来获取。
CPU的高速缓存策略各不相同,但RAM连续块通常存储在缓存中(译注:因为程序运行时对内存的访问呈现局部性(Locality)特征。这种局部性既包括空间局部性(Spatial Locality),也包括时间局部性(Temporal Locality)。有效利用这种局部性,缓存可以达到极高的命中率。不清楚的可以回去补下课)。这意味着,如果你的应用程序的工作在连续的内存块(如一个Vector)上并且大小不超过高速缓存大小限制,那么CPU高速缓存将被命中,而不是从RAM中读取,将收获一个大的性能取胜。
用一个有点做作的例子来证明这一点,访问一个大Vector中所有的元素模拟RAM。分别顺序访问,随机访问它们。为了消除Math.random调用的影响,通过2个Vector来存储访问元素的索引值。在随机访问的情况下,Vector中存的索引值是随机的,这样元素将被随机读取。下面是10个元素的向量的例子,两个索引值Vector可能如下所示:
/ /顺序访问(索引Vector中存储的index值) 0 1 2 3 4 5 6 7 8 9 / /随机访问(索引Vector中存储的index值) 2 3 9 1 4 0 6 8 5 7 |
测试运行的环境:
Release version of Flash Player 12.0.0.41
2.3 Ghz Intel Core i7-3615QM (256 KB L2 per core, 6 MB L3 cache)
Mac OS X 10.9.1
Google Chrome 32.0.1700.77
ASC 2.0.0 build 354071 (-debug=false -verbose-stacktraces=false -inline -optimize=true)
测试得到的结如下:
访问方式 | 耗时 |
顺序 | 27 |
随机 | 169 |
由此我们可以看到使用了CPU缓存的顺序访问,比没有使用CPU缓存的随机访问性能高6+倍。访问内存的顺序真的很重要!
诚然上面的例子有点做作,但下面的例子是处理实际问题:遍历BitmapData的像素。需要一个循环来遍历行(Y),一个循环来遍历列(X)。哪个作为外循环,哪个作为内循环?
实际上,BitmapData是“逐行”存储的。下面是3x2 BitmapData:
(0,0) (1,0) (2,0) (0,1) (1,1) (1,2)
如果外循环是遍历列(X),访问这些内存的地址如下:
0 4 8 1 5 9 2 6 10 3 7 11
但是如果外循环是遍历行(Y),访问顺序如下:
0 1 2 3 4 5 6 7 8 9 10 11
正如我们上面所了解到,顺序访问可以利用CPU缓存。似乎只是跳序了一点点,但是当BitmapData实例很大的时候问题开始真正出现。如果BitmapData为2048×2,前四个内存访问将是0,2047,1,2048。
下面的例子比较了2048×2048的BitmapData这两种循环策略,测试环境与上面的相同:
BITMAPDATA外循环 | 耗时 |
行 | 89 |
列 | 348 |
这里的性能优势不像上面访问Vector那么大,但遍历相同的像素时它仍然是高达4倍的优势。如果BitmapData是更大的,优势只会更大。这在CPU的缓存比我的测试环境中少的情况更明显。
下面是测试应用程序的源代码:
package{import flash.display.BitmapData;import flash.display.Sprite;import flash.display.StageAlign;import flash.display.StageScaleMode;import flash.text.TextField;import flash.text.TextFieldAutoSize;import flash.utils.getTimer;public class CacheTest extends Sprite{private var logger:TextField = new TextField();private function row(...cols): void{logger.appendText(cols.join(",")+"\n");}public function CacheTest(){stage.scaleMode = StageScaleMode.NO_SCALE;stage.align = StageAlign.TOP_LEFT;logger.autoSize = TextFieldAutoSize.LEFT;addChild(logger);testVector();row();testBitmapData();}private function testVector(): void{const SIZE:int = 10000000;var beforeTime:int;var afterTime:int;var i:int;var sum:int;// Build vectors of indicesvar inOrder:Vector.<int> = new Vector.<int>(SIZE);for (i = 0; i < SIZE; ++i){inOrder[i] = i;}var randomOrder:Vector.<int> = inOrder.slice();shuffle(randomOrder);row("Vector Access", "Time");sum = 0;beforeTime = getTimer();for (i = 0; i < SIZE; ++i){sum += inOrder[inOrder[i]];}afterTime = getTimer();row("Sequential", (afterTime-beforeTime));sum = 0;beforeTime = getTimer();for (i = 0; i < SIZE; ++i){sum += randomOrder[randomOrder[i]];}afterTime = getTimer();row("Random", (afterTime-beforeTime));}private function testBitmapData(): void{var SIZE:int = 2048;var bmd:BitmapData = new BitmapData(SIZE, SIZE, true, 0xff123456);var curRow:int;var curCol:int;var sum:int;var beforeTime:int;var afterTime:int;row("BitmapData Outer Loop", "Time");sum = 0;beforeTime = getTimer();for (curRow = 0; curRow < SIZE; ++curRow){for (curCol = 0; curCol < SIZE; ++curCol){sum += bmd.getPixel32(curCol, curRow);}}afterTime = getTimer();row("Row", (afterTime-beforeTime));sum = 0;beforeTime = getTimer();for (curCol = 0; curCol < SIZE; ++curCol){for (curRow = 0; curRow < SIZE; ++curRow){sum += bmd.getPixel32(curCol, curRow);}}afterTime = getTimer();row("Col", (afterTime-beforeTime));}private function shuffle(vec:Vector.<int>): void{var len:uint = vec.length;while (len){var index:uint = Math.floor(Math.random() * len);len--;var temp:int = vec[len];vec[len] = vec[index];vec[index] = temp;}}}}
运行测试程序(http://files.jacksondunstan.com/articles/2491/CacheTest.swf)。