• 沒有找到結果。

字串操作加速目標分析

第三章 Java 字串處理加速器設計

3.5 Hardware Native Interface

3.5.2 字串操作加速目標分析

為了加速 JAIP 之字串操作性能,我們針對 Java 標準字串類別庫中的 String 以及 StringBuffer 之中的基本操作進行分析。本小節是詳細描述 arraycopy 及 indexOf 兩個 Java method 在字串操作之中之重要性。此分析是與後文 4.3.1 小節 中,字串處理程式之 method profile 是吻合的。

多數修改字串的方法會使用到 arraycopy,arraycopy 執行的效能若太差,很容 易影響整個字串操作程式。在過去 JAIP 對 arraycopy 的實作中[20],是使用 IPC 介面來觸發 RISC 核心上定義好的 arraycopy 原生方法,而這樣的設計讓 JAIP 耗 費相當可觀的執行時間開銷。本小節開頭先介紹 arraycopy 使用時機,而後介紹本 論文的 arraycopy 方法使用介面及設計。

arraycopy 方法在 String 類別裡面是相當重要的一個方法,它被直接或間接呼 叫的 call graph 如下圖 14 所示,此圖畫出了 CLDC 版本之 String 類別方法對 arraycopy 使用情況。由於字串的存放空間在 JVM 屬於 Permanent Generation,此 種空間永久不被 Garbage Collection 回收,直到 Java 程式結束。因此每當字串內 容被更改時,都必須創建新的字串物件來存放被修過的字串內容。而每次將新字 串內容存放到新的字串物件時,都會直接或間接用到 arraycopy。例如當我們使用 concat(String)將 B 字串接到 A 字串之後端時,一種實作方法便是先創建新的字串 物件,將 A 字串利用 arraycopy 拷貝到新物件,再將 B 字串利用 arraycopy 拷貝到 新字串物件的尾端。

29

圖 14 String 類別裡 arraycopy 直接或間接呼叫關係圖

字串處理程式常用的類別有 StringBuilder 及 StringBuffer,兩種類別都是提供 一個字串緩衝空間,這個緩衝空間大小是預先設定好的,任何需要大量被操作的 字串在每次操作結束都可以先暫存在緩衝空間中,等到所有操作結束後,再利用 toString 方法將緩衝空間內的字串內容轉換成為真正的 String 類別,操作過程中,

如 遇 到 空 間 不 足 時 , 利 用 expandCapacity 方 法 增 加 空 間 。 StringBuilder 及 StringBuffer 的差別在於 StringBuffer 是 thread-safe 的,而 StringBuilder 只適合在 single-thread 程式中使用。StringBuffer 裡面常用的方法有 append、insert 等等,這 兩個除了本身就會呼叫 arraycopy 之外,有時候還會透過兩個 private 的方法,

expandCapacity 及 copy 間接使用 arraycopy。expandCapacity 是當 StringBuffer 空 間不足的時候,expandCapacity 會宣告新的字元陣列空間,而後會將字串值透過 arraycopy 從舊的空間拷貝到新的空間。copy 則是為了支援快速的 toString 方法,

toString 時僅將字元陣列的位址賦予給字串物件,任何會修改到 StringBuffer 字元 陣列內容時,採取 copy-on-write 策略,而 copy 這個 private 方法就是在這個時候 被使用,copy 的實作也是使用 arraycopy。

30

圖 15 StringBuffer 類別裡 arraycopy 直接或間接呼叫關係圖

在 Java String 類別中,indexOf 功能是進行子字串或字元搜尋:在一個本文 t 中,找尋是否存在一個 string pattern s 或字元 c,並回傳其最小索引值 k 使得 t[k:k+nc] = s 或 t[k] = c。此方法應用很廣泛,例如 DNA 序列檢驗,網路封包檢查。

而與字串處理本身相關性較強的應用,存在於許多腳本語言解析器或 xml 解析器。

例如某個語言的 parser 要檢查一個 identifier 的字元是否為合法的字元,這時就可 以使用 indexOf()來搜尋 identifier 的字元是否存在於一個由所有合法的字元組合起 來的文本中。indexOf 也可以做為 substring 的輔助工具。例如 xml parser 要切開 xml 標籤中的 namespace 與 prefix 的時候,可以使用 indexOf 找尋其”:”字元之索引 值,在透過其索引值使用 substring 之 method。目前在我們的系統中,共有 3 個 Java methods 會直接使用 Hardware Native Interface 來呼叫 indexOf accelerator,如 表 3 所示。3 個 method 會分別使用 3 種不同的信號線觸發其加速器,因此加速器 可 以 很 容 易 地 知 道 參 數 型 態 和 工 作 項 目 。 其 中 String.indexOf(String str, int fromIndex)會透過加速器內部的 Object Resolution Unit 解析其物件的 field 以取得 更 細 部 的 參 數 。 因 此 , 不 需 要 額 外 的 程 式 碼 來 傳 遞 或 轉 換 參 數 。 String.indexOf(String str, int fromIndex)是典型的 string matching 操作,呼叫它的 object instance 及第一個 String object 參數分別代表 text 及 string pattern。

31

String.indexOf(int char, int fromIndex)除了 string pattern 參數是直接使用字元以外,

與上者之操作內容相同。

表 3 透過 Hardware Native Interface 使用 indexOf accelerator 之 Java methods

Methods using the indexOf Accelerator

String.indexOf(String str, int fromIndex) String.indexOf(int char, int fromIndex)

String.lastIndexOf(int char, int fromIndex)