2012-09-28 92 views
6

我目前正在研究如何使用SSE 4.2字符串和文本處理指令STTNI(http://software.intel.com/zh-cn/articles/xml-parsing-accelerator-with- intel-streaming-simd-extensions-4-intel-sse4 /)以獲得高效的CSV文件解析。SSE 4.2 CSV文件解析

我的問題是,如果這已經被嘗試過之前的CSV文件/內存中的CSV解析,並且如果例子可以在線?到目前爲止,我沒有找到有關如何使用SSE 4.2進行文本解析的好資源(除了上面提到的英特爾文章)。

我想目前的策略是,爲每個16個字節,創建4位掩碼:

  • 一個每個字符對分隔符
  • 一個對換行字符的每個字符匹配匹配
  • 一個匹配引號字符(字符串)的每個字符;和
  • 一個匹配對轉義字符的每個字符(逸出定界符,換行符引號)

與由它很容易確定的偏移和長度在CSV每個值的位掩碼中獲得的信息。

+2

請注意,引號字符可能會被轉義,這可能很難用您繪製的方法處理。 –

+0

從已刪除的僅鏈接答案:[github:'csvmonkey'](https://github.com/dw/csvmonkey)上有一個工作(但不是生產就緒)實現。 C++頭只庫。這很快,但「現在它主要是玩具代碼。」也許一個好的起點,除了沒有許可證列出。 –

回答

5

你爲什麼要使用位掩碼?用單個STTNI指令檢查所有這些事件不是更好嗎,然後使用返回的索引來處理返回的事件(如果有)?

(編輯) 讓我嘗試更多的幫助......

(我假設你使用的是8位字符的空終止字符串。讓我知道這是不是這樣的。)

我認爲你最好把分隔符,換行符,引號和換碼放到一個寄存器中(作爲空終止的字符串),並使用PCMPISTRI而不是PCMPISTRM使用每個值。對於控制字你要表明:無符號字節,等於任何,正極性,最小。 (很確定我沒錯。)

然後,您可以使用JA來同時檢查是否有4個特殊字符被擊中或達到了字符串末尾。如果是這樣,逃避循環來處理它。如果不是,則將ECX添加到xmm2/m128指針並跳回到PCMPISTRI。

處理「命中」的代碼的第一條指令是將ECX添加到xmm2/m128指針,然後依次處理每個可能性。我建議最可能的是從最不可能的順序排列。

因此,ASM最終應該看起來像:

XOR  ECX, ECX 

TAG1: 
    ADD  EAX, ECX 
    PCMPISTRI XMM1, [EAX], 0x0  ; also writes ECX = index 
    JA  TAG1 

ADD  EAX, ECX 
CMP  BYTE PTR[EAX], "delimiter" 
JE  "handle delimiter" 
CMP  BYTE PTR[EAX], "newline" 
JE  "handle newline" 
CMP  BYTE PTR[EAX], "quotation" 
JE  "handle quotation" 
CMP  BYTE PTR[EAX], "escape" 
JE  "handle escape" 
CMP  BYTE PTR[EAX], "end of string" 
JE  "handle end of string" 

我會讓你決定什麼纔是測試分隔符的最佳順序是。 :)

當我開發指令時,我曾經能夠讓編譯器使用內在函數生成上面的asm代碼。我已經完成了指令的工作已經有一段時間了,但不知道平均編譯器是否能夠正常工作。 (聽到你得到的結果會很有趣。)


順便說一句,指令面具的版本也有各種用途,他們只是沒有尋找,因爲指令的「I」版本中的第一個或最後的東西是最好的選擇會爲你計算抵消額。面具版本適用於計數或僅處理其他更奇特的東西中的某些項目。現在我用它們來計算DNA字符串中的A,C G和T。

+0

謝謝Mike,這聽起來很棒!我會告訴你我能想出什麼。 – muehlbau