基于通用寄存器SWAR的SIMD strlen函数页错误问题求助
SWAR实现的汇编strlen页错误问题解决
我实现了一个基于通用寄存器SWAR技术(不使用XMM寄存器或SSE指令)的汇编strlen函数,接收字符数组形式的字符串指针。它以8字节为步长通过位操作检测字符串结束符0,检测到可能包含结束符时转为逐字节检测。逻辑可行,但运行时出现页错误异常,即便最后阶段是逐字节迭代的。
原汇编代码:
; rdi <- const *char ; rax <- counter + return value ; rbx <- current array ; rcx <- Bitmask ; rsi <- Arr for calculation strlen: PUSH rbx PUSH rbp MOV rbp,rsp SUB rsp,8 ; calling convention XOR rax,rax MOV rcx,0x7F7F7F7F7F7F7F7F while_parallel: ;checks if next 8 byte contains end - zero MOV rbx,[rdi+rax] MOV rsi,rbx AND rsi,rcx ADD rsi,rcx OR rsi,rbx OR rsi,rcx NOT rsi CMP rsi, qword 0 JNE while_single ADD rax,8 JMP while_parallel while_single: ;check if next byte is zero CMP [rdi+rax],byte 0 JE end INC rax JMP while_single end: ADD rsp,8 POP rbp POP rbx RET
注:不能使用任何SSE指令或XMM寄存器。
问题根源
页错误的核心原因是并行检测阶段直接读取8字节数据,而字符串末尾可能跨页:比如字符串最后几个字节在当前页的末尾,下一个字节属于未映射的内存页,此时一次性读取8字节就会触发页错误——哪怕逐字节读取时只会访问到有效内存,不会碰无效页。
另外原SWAR检测逻辑存在错误,可能漏检零字节,导致循环继续读取越界内存,进一步加剧页错误概率。
解决方案
- 添加页边界检查:每次读取8字节前,先计算当前位置到4KB页末尾的剩余字节数,若不足8字节则直接切换到逐字节检测,避免跨页读取无效内存。
- 修正SWAR零字节检测逻辑:使用行业通用的可靠检测公式,确保准确识别包含零字节的8块数据。
修正后的汇编代码
; rdi <- const char* 输入字符串指针 ; rax <- 返回值 字符串长度 strlen: PUSH rbx PUSH rbp MOV rbp, rsp SUB rsp, 8 ; 符合System V AMD64调用约定的栈对齐要求 XOR rax, rax MOV rcx, 0x0101010101010101 ; SWAR检测用掩码1 MOV rdx, 0x8080808080808080 ; SWAR检测用掩码2 while_parallel: ; 计算当前位置到4KB页末尾的剩余字节数 MOV rbx, rdi ADD rbx, rax AND rbx, 0xFF8 ; 取当前地址的页内偏移(4KB页大小) MOV rsi, 0x1000 SUB rsi, rbx ; rsi = 页内剩余字节数 CMP rsi, 8 JB while_single ; 剩余不足8字节,直接逐字节检测 ; SWAR方式检测8字节块中是否存在零字节 MOV rbx, [rdi + rax] MOV rsi, rbx SUB rsi, rcx ; 每个字节减0x01,零字节会溢出为0xFF NOT rbx AND rsi, rbx ; (b-1) & ~b ,仅当b=0时结果为0xFF AND rsi, rdx ; 仅保留每个字节的最高位,非零则存在零字节 CMP rsi, 0 JNE while_single ; 检测到零字节,切换到逐字节定位 ADD rax, 8 JMP while_parallel while_single: ; 逐字节检测结束符 CMP byte [rdi + rax], 0 JE end INC rax JMP while_single end: ADD rsp, 8 POP rbp POP rbx RET
说明
- 页边界检查基于4KB标准页大小,若系统使用其他页大小,需调整
0xFF8和0x1000对应的值。 - 修正后的SWAR检测逻辑通过
(val - 0x0101010101010101) & ~val & 0x8080808080808080判断零字节,是通用且可靠的无SIMD零检测方案。
内容的提问来源于stack exchange,提问作者HeapUnderStop
相关产品推荐
相关产品推荐

