2012-09-28 174 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