【词汇】Google doc & Cache、prefetch and cpu

Google doc

 google 文件

  谷歌办公套件,类似于微软的Office的一套在线办公软件,可以处理和搜索文档、表格、幻灯片,并可以通过网络和他人分享,有google的帐号就能使用.

  Google 文件是基于网络的文字处理和电子表格程序,可提高协作效率。有了此程序,您就可以把文档放在网上。这样,您团队中的其他人就可以实时在线对文档进行编辑和更新,免去您线下发送相同版本的文档并根据每个不同的回复对相同文档进行反复更新。多名用户可同时在线更改文件,并可以实时看到其他成员所作的编辑。系统会自动为您保存每次的修订,这样您就可以看出来谁在何时作了什么修改,并可恢复到之前任何一个时间点的旧版本。

  文件可以很方便地从 Google 文件导入及导出。若要从保存在您计算机上的现有文件开始操作,只要上传该文档,并从您上次停止的地方继续进行即可。要离线使用文档或将其作为附件分发,只需以最适合您的格式在您自己的计算机上保存一份 Google 文件副本即可。无论您是上传还是下载文件,所有的格式都会予以保留。

  就像 Google 的其他网络服务一样,您不需要下载或安装另外的软件。您只需一台接入互联网的计算机及可使用 Google 文件的标准浏览器即可。

  概要

  创建在线文档 - 从头开始创建新文档,或从您的计算机上传已保存的文档。从任一台接入互联网的计算机修改文档。

  实时协作 - 即使您与您邀请的其他人处在不同位置,您也能与他们同步处理文档。

  修订历史记录 - 各项修改记录都会予以保留,让您看到什么人在什么时间添加和删除了什么内容。

  搜索工具 - 就像 Gmail 一样,有了 Google 文件,您就可以利用 Google 的搜索能力,来查找已数月未修改过的文档。

  安全和隐私 - 由您选择可查看您文档的对象和时间。只有当您将用户添加至协作者或查看者的列表或者决定将文档公开时,其他用户才能访问您的文件。管理员能够对内部和外部文档共享设定限制。

  集成 - 用户从贵组织机构的初始页即可访问其 Google 文件。Google 电子表格数据 API 还允许其他应用程序显示和更新电子表格的内容。

  支持的浏览器 - Microsoft Internet ExplorerMozilla FirefoxGoogle Chrome Netscape

  支持的语言 - 保加利亚语、加泰罗尼亚语、简体中文、繁体中文、克罗地亚语、捷克语、丹麦语、荷兰语、美式英语、英式英语、菲律宾语、芬兰语、法语、德语、希腊语、北印度语、匈牙利语、印度尼西亚语、意大利语、日语、韩语、拉脱维亚语、立陶宛语、挪威语、波兰语、葡萄牙语(葡萄牙)、葡萄牙语(巴西)、罗马尼亚语、俄语、塞尔维亚语、斯洛伐克语、斯洛文尼亚语、西班牙语、瑞典语、乌克兰语、泰国语、土耳其语、越南语。

 

Cacheprefetch and cpu

文档内容简介:

  這篇文章主要是探討現在的 CPU cache 和記憶體系統之間的關係。

 

目录:

  [Part 1]

  [Part 2]

 

文档内容:

 

[Part 1]

  CPU 速度的進展,一直比記憶體的速度進展要來得快。在 IBM PC XT 的時代,CPU 和記憶體的速度是差不多的。不過,後來 CPU 的速度就愈來愈快。再加上 DRAM 需要 refresh 才能保存資料的特性,DRAM 很快就跟不上 CPU 的速度了。現在的 CPU 都利用了 pipeline 的方式,可以每個 cycle issue 一個(甚至多個)指令,再加上現在的 CPU 時脈也比記憶體的時脈高,記憶體的速度可說是遠遠落在 CPU 之後了。

  為了避免記憶體成為 CPU 速度的瓶頸,現在的 CPU 都有 cache 的設計,甚至還有多層的 cacheCache 的原理,主要是利用到大部分的程式,在處理資料時,都有一定程度的區域性。所以,我們可以用一小塊快速的記憶體,來暫存目前需要的資料。

 

  例如,幾乎所有的程式,大部分的執行時間是花在一些迴圈中。這些迴圈通常都不大,可能只佔整個程式空間的百分之一。如果一個程式經常要執行這段程式數千、甚至數萬次,那就可以把這一小段程式放在 cache 中,CPU 就不需要每次都到很慢的主記憶體中讀取這段程式了。很多一般用途的程式,在存取資料時,也有類似的特性。因此,cache 的幫助非常大。如果沒有 cache 的話,我們就不需要這麼快的 CPU 了,因為系統的速度會卡在記憶體的速度上面。

 

  現在的 CPU 往往也有多層的 cache。例如,Intel Pentium III 500Mhz CPU,有 32KB L1 cache,和 512KB L2 cache。其中,L1 cache 內建在 CPU 內部,速度非常快,而且它是 Harvard 式,即指令用的空間和資料用的空間是分開的。Pentium III 500Mhz CPU L1 cache 是分成 16KB I-cache 16KB D-cache。而 L2 cache 則是在 CPU 外面,以 250Mhz 的速度運作。另外,它和 CPU 之間的 bus 也只有 64 bits 寬。L2 cache 通常就不會區分指令和資料的空間,也就是 unified cache

 

  Cache 對速度有什麼影響呢?這可以由 latency 來表示。CPU 在從記憶體中讀取資料(或程式)時,會需要等待一段時間,這段時間就是 latency,通常用 cycle 數表示。例如,一般來說,如果資料已經在 L1 cache 中,則 CPU 在讀取資料時(這種情形稱為 L1 cache hit),CPU 是不需要多等的。但是,如果資料不在 L1 cache 中(這種情形稱為 L1 cache miss),則 CPU 就得到 L2 cache 去讀取資料了。這種情形下,CPU 就需要等待一段時間。如果需要的資料也不在 L2 cache 中,也就是 L2 cache miss,那麼 CPU 就得到主記憶體中讀取資料了(假設沒有 L3 cache)。這時候,CPU 就得等待更長的時間。

 

  另外,cache 存取資料時,通常是分成很多小單位,稱為 cache line。例如,Pentium III cache line 長度是 32 bytes。也就是說,如果 CPU 要讀取記憶體位址 0x00123456 的一個 32 bits word(即 4 bytes),且 cache 中沒有這個資料,則 cache 會將 0x00123440 ~ 0x0012345F 之間的 32 bytes 資料(即一整個 cache line 長度)都讀入 cache 中。所以,當 CPU 讀取連續的記憶體位址時,資料都已經讀到 cache 中了。

 

  我寫了一個小程式,用來測試 cache 的行為。這個程式會連續讀取一塊記憶體位址,並量測平均讀取時間。這個 程式的執行結果如下:

 

測試平台:

 

Pentium III 500Mhz, PC100 SDRAM, 440BX chipset

Celeron 466Mhz, PC100 SDRAM, VIA Apollo Pro 133 chipset

 

 

程式的執行檔和原始碼可在這裡下載。

 

  由上面的結果可以看出,當測試的區塊大小在 16KB 以下時,平均的 latency 都在 1 ~ 3 cycles 左右。這顯示出 16KB L1 D-cache 的效果。在測試區塊為 1KB 2KB 時,因為額外的 overhead 較高,所以平均的 latency 變得較高,但是在 4KB ~ 16KB 的測試中,latency 則相當穩定。在這個範圍中,由於 Pentium III Celeron 有相同的 L1 cache,所以測試結果是幾乎完全相同的。

 

  在區塊超過 16KB 之後,就沒辦法放入 L1 D-cache 中了。但是它還是可以放在 L2 cache 中。所以,在 Pentium III 的情形下,從 32KB ~ 512KBlatency 都在 10 cycles 左右。這顯示出當 L1 cache miss L2 cache hit 時,所需要的 latency。而 Celeron L2 cache 只有 128KB,但是 Celeron L2 cache latency 則明顯的比 Pentium III 為低。這是因為 Celeron L2 cache on-die,以和 CPU 核心相同的速度運作。而 Pentium III L2 cache 則是分開的,且以 CPU 核心速度的一半運作。

 

  在區塊超過 512KB 之後,L2 cache 就不夠大了(Pentium III 500Mhz 只有 512KB L2 cache)。這時,顯示出來的就是 L1 cache miss L2 cache miss 時,所需要的 latency。在 1024KB 或更大的區塊中,Pentium III latency 都大約是 28 cycles 左右,而 Celeron latency 則超過 70 cycles。這是 CPU 讀取主記憶體時,平均的 latency。而 Celeron latency 較高,應該是因為其外頻較低,而倍頻數較高的緣故(Pentium III 500Mhz 5 倍頻,而 Celeron 466 7 倍頻)。另外,晶片組的差異也可能是原因之一。

 

  Cache 的效果十分明顯。不過,有時候 cache 是派不上用場的。例如,當資料完全沒有區域性,或是資料量太大的時候,都會讓 cache 的效果降低。例如,在進行 MPEG 壓縮時,存取的資料量很大,而且資料的重複利用率很低,所以 cache 的幫助就不大。另外,像是 3D 遊戲中,如果每個 frame 的三角面個數太多,也會超過 cache 能夠處理的範圍。

 

  現在的電腦愈來愈朝向「多媒體應用」,需要處理的資料量也愈來愈大,因此,要如何善用 cache 就成了一個重要的問題。一個非常重要的方法,就是把讀取主記憶體的 latency 和執行運算的時間重疊,就可以把 latency「藏」起來。通常這會需要 prefetch 的功能,也就是 AMD K6-2 及之後的 CPU,和 Intel Pentium III 之後的 CPU 加入的新功能。在下一篇文章中,我們會討論 prefetch 的原理和用途。

 

 

[Part 2]

  在上一篇文章中,已經簡單討論過 CPU cache 和其對 latency 的影響。在這篇文章中,我們就以一個較為實際的例子,並說明 prefetch 的原理和用途。

 

  這裡要用的「實際例子」,其實還是很理想化的。為了和 3D 繪圖扯上一點關係,這裡就用「4x4 的矩陣和 4 維向量相乘」做為例子。不過,一般在 3D 繪圖中,都是用 single precision 的浮點數(每個數需要 32 bits),而這裡為了讓記憶體的因素更明顯,我們使用 double precision 的浮點數(每個數需要 64 bits),也就是一個 4 維向量剛好需要 32 bytes

 

在這個例子中,我們採取一個 3D 繪圖中,相當常見的動作,也就是把一大堆 4 維向量,乘上一個固定的 4x4 矩陣。如果向量的個數非常多,超過 CPU cache 所能負擔,那麼 CPU 的表現就會大幅下降。

 

為了讓大家心裡有個底,這裡先把執行的結果列出來:

 

測試平台: Pentium III 500Mhz, PC100 SDRAM, 440BX chipset

 

 

 

在程式集可以下載程式的原始碼和執行檔。

 

  首先,我們來看沒有使用 prefetch 指令的結果。事實上,結果相當符合預測。在 L1 D-cache 的範圍內(即小於 16KB 的情形),平均的運算時間相當的穩定,約在 51 ~ 52 cycles 左右。這也是 Pentium III 在計算一個 4x4 矩陣和 4 維向量相乘時(使用 double precision 浮點數),可能達到的最快速度。當然,這個程式是用 C 寫成的。如果直接用手寫組合語言,可能還可以再快個 5 ~ 10 cycles

 

  當資料量超過 L1 D-cache 的範圍,但是還在 L2 cache 的範圍之內時,所需的時間提高到約 60 cycles 左右。在 Part 1 中,我們已經知道 Pentium III 500Mhz L2 cache 大約有 10 cycles latency,所以這個結果也是相當合理的。

 

  當資料量超過 L2 cache 的範圍時,所有的資料就需要從主記憶體中取得了。從圖上可以很容易的看到,每次運算所需的時間增加到 145 ~ 150 cycles。這有點出乎意料之外:在 Part 1 中,讀取主記憶體的 latency 只有 30 cycles 左右,但是在這裡,latency 增加了約 100 cycles。不過,這個結果並不奇怪。因為在運算結束後,運算的結果必須要寫回記憶體中,而寫回記憶體的動作,需要很多時間。

 

  從這裡可以看到,在資料量超過 L2 cache 的範圍時,CPU 可說是被記憶體的速度限制住了。事實上,如果記憶體的速度不變,那即使是用兩倍快的 CPU,速度的增加也會非常有限。以 3D 遊戲的角度來說,1024KB 2048KB 這樣的資料量並不算少見,因為一個 single precision 浮點數的 4 維向量,就需要 16 bytes 的空間。65,536 4 維向量就需要 1MB 的空間了。

 

  事實上,記憶體的速度雖慢,但是要完成一個 32 bytes(一個四維向量的大小)的讀寫動作,也只需要 60 ~ 70 cycles 而已(以 Pentium III 500Mhz 配合 PC100 SDRAM 的情形來算)。而在不用 prefetch 的情形下,CPU 的動作類似下圖所示:

 

 

 

在上圖中,CPU 的運算單元(即圖中的 Execution Units)大部分的時間都在等待資料輸入。而 Load/Store Unit 也有不少時間是不動作的。這顯然不是最好的方法,因為 CPU 的兩個單元都不是全速運作。

 

如果我們在 CPU 的運算單元進行計算工作時,就把下一個要計算的資料先載入到 CPU cache 中,那麼,CPU 的動作就會變成類似下圖所示:

 

 

 

現在,Load/Store Unit 變成全速運作了。Execution Units 還是沒有全速運作,但是這是沒辦法的。這種情形,就表示出瓶頸是在 Load/Store Unit,也就是在主記憶體的速度。已經沒有任何方法可以加快執行的速度了(除非加快記憶體的速度)。

 

要注意的一點是,上面的情形是很少發生的真實世界中的。實際的程式,通常瓶頸都是在運算單元。不過,我們的例子則剛好不是這樣(因為矩陣和向量相乘是很簡單的運算),而是類似圖中的情形。

 

要怎麼告訴 CPU,在計算的同時將下一個資料載入到 cache 中呢?這時就要用到 prefetch 的指令了。在我們的程式中,執行向量運算的程式如下:

 

for(i = 0; i < buf_size; i += 4) {

double r1, r2, r3, r4;

 

// 執行矩陣乘法

r1 = m[0] * v[i] + m[1] * v[i+1] + m[2] * v[i+2] + m[3] * v[i+3];

r2 = m[4] * v[i] + m[5] * v[i+1] + m[6] * v[i+2] + m[7] * v[i+3];

r3 = m[8] * v[i] + m[9] * v[i+1] + m[10] * v[i+2] + m[11] * v[i+3];

r4 = m[12] * v[i] + m[13] * v[i+1] + m[14] * v[i+2] + m[15] * v[i+3];

 

// 寫回計算結果

v[i] = r1;

v[i+1] = r2;

v[i+2] = r3;

v[i+3] = r4;

}

現在,我們在矩陣乘法的前面插入一個 prefetch 指令,變成:

 

for(i = 0; i < buf_size; i += 4) {

double r1, r2, r3, r4;

 

// 執行矩陣乘法

r1 = m[0] * v[i] + m[1] * v[i+1] + m[2] * v[i+2] + m[3] * v[i+3];

// 前一行執行完後,整個 4 維向量已經載入到 cache 中。

// 所以,現在用 prefetch 指令載入下一個 4 維向量。

prefetch(v + i + 4);

// 繼續進行計算

r2 = m[4] * v[i] + m[5] * v[i+1] + m[6] * v[i+2] + m[7] * v[i+3];

r3 = m[8] * v[i] + m[9] * v[i+1] + m[10] * v[i+2] + m[11] * v[i+3];

r4 = m[12] * v[i] + m[13] * v[i+1] + m[14] * v[i+2] + m[15] * v[i+3];

 

// 寫回計算結果

v[i] = r1;

v[i+1] = r2;

v[i+2] = r3;

v[i+3] = r4;

}

這段程式中的 prefetch 函式,裡面執行的是 SSE prefetchnta 指令。Pentium III Athlon 都支援這個指令(AMD K6-2 中另外有一個 prefetch 指令,是 3DNow! 指令的一部分)。這個指令會將指定的資料載入到離 CPU 最近的 cache 中(在 Pentium III 即為 L1 cache)。

 

只不過加上這樣一行程式,執行結果就有很大的不同。回到前面的測試結果,我們可以看出,prefetch 指令,在資料已經存在 cache 中的時候,會有相當程度的 overhead(在這裡是大約 10 cycles)。但是,當資料不在 cache 中的時候,效率就有明顯的改善。特別是在資料量為 1024 KB 時,所需時間約為 70 cycles,說明了瓶頸確實是在 Load/Store Unit。在 1024 KB 之後,所需的 cycle 的增加,則是因為在多工系統中難以避免的 task switch 所產生的 overhead

 

  由此可知,prefetch 指令對於多媒體及 3D 遊戲等資料量極大的應用,是非常重要的。也可以預料,將來的程式一定會更加善用這類的功能,以達到最佳的效率。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值