人脑的容量有限,为了在有限的脑容量中高效的存储更多的知识,需要对知识进行归纳整理,变成自己的文章。但是并不是所有的知识都能够变成文章,出于篇幅、与其他知识点的关联等原因,很多知识当前还处于一种零散状态。

为了更有效的管理这些零散知识,现在将它们都存储在博客中的这个模块之中。当某些知识变成了一种常识或者许多知识积累了足够的信息量能够写一篇文章,则这些知识就会从这里删除。

计算机类一般性知识

Siphash算法

SipHash是由BLAKE算法的设计者Jean-Philippe Aumasson等人于2012年设计的,它是一类针对短消息设计的伪随机函数族,可用于消息认证,用途一般与MAC算法相似。

SipHash算法通过让输出随机化,能够有效减缓哈希洪水攻击凭借这一点,它逐渐成为Ruby、Python、Rust等语言默认的Hash表实现的一部分。

规则学习

规则学习是机器学习的一个子领域,专注于从数据中学习出能够描述数据分布所隐含的客观规律或领域概念的规则。这些规则通常以“如果…那么…”的形式表示,能够用于对未见示例进行判别

经典类型的规则学习算法与一般性的深度学习相比, 似乎并无明显优势. 唯一的优势是更加具备可解释性. 但如果是多个因子的复杂组合, 那么其可读性也未必比深度学习 有多高.

SIMD如何加速JSON反序列化

SIMD(单指令多数据)通过并行处理多个字符来加速JSON反序列化,尤其是在扫描结构字符(如引号、冒号)和批量处理数据时效果显著。以下是一个简化示例:

假设需要解析JSON字符串:"name":"John",目标是快速定位键值对的分隔符冒号 :


传统逐字符扫描

1
2
3
4
5
6
const char* str = "\"name\":\"John\"";
for (int i = 0; i < strlen(str); i++) {
if (str[i] == ':') { // 逐个字符比较
return i; // 找到冒号位置
}
}

SIMD优化示例(伪代码)

使用SSE指令集(128位寄存器,一次处理16个字符):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <emmintrin.h>  // SSE2头文件

int find_colon(const char* str) {
// 加载16字节到SIMD寄存器
__m128i chunk = _mm_loadu_si128((__m128i*)str);

// 创建包含16个冒号ASCII值的向量
__m128i colon = _mm_set1_epi8(':');

// 并行比较每个字节是否等于冒号
__m128i cmp = _mm_cmpeq_epi8(chunk, colon);

// 生成掩码(0xFFFF中对应匹配的位置为1)
int mask = _mm_movemask_epi8(cmp);

// 找到第一个匹配的位(返回索引)
return __builtin_ctz(mask);
}

关键优化点

  1. 批量比较:一次比较16个字符,而非逐个检查。
  2. 快速掩码生成:通过位操作(如__builtin_ctz)快速定位匹配位置。
  3. 减少分支预测失败:避免循环中的条件判断。

实际应用场景

结构字符扫描:快速定位{}, [], ,, :等符号。
转义字符处理:批量搜索反斜杠\的位置。
数值解析:并行处理数字字符(如"value":1234中的1234)。


性能对比

传统方式:需循环N次(时间复杂度O(N))。
SIMD方式:仅需N/16次循环(理论加速16倍,实际受内存对齐等因素影响)。

通过将重复性字符操作向量化,SIMD显著减少了JSON解析中耗时的扫描步骤。


SIMD加速JSON解析的实践与思考

JSON解析常被认为难以利用SIMD加速, 因为其包含大量分支跳转(处理转义字符、类型推断、括号匹配等)。但现代解析器通过架构分层设计, 在特定环节实现了3-5倍的SIMD加速。我们通过几个关键优化点来解析这个矛盾。

阶段分离策略
高效解析器的核心是将任务拆分为两个阶段:

1
2
3
4
5
6
7
8
9
10
// 阶段1: SIMD预扫描 (向量化友好)
simd_buffer = load_64bytes(json); // AVX-512加载
quote_mask = simd_check_quotes(simd_buffer); // 批量检测引号
struct_mask = quote_mask ^ (quote_mask >> 1); // 生成结构位图

// 阶段2: 语义解析 (分支密集型)
while(!struct_mask.empty()) {
if(current_char == '"') handle_string(); // 不可避免的分支
else if(isdigit(*p)) parse_number(); // 类型判断
}

第一阶段用SIMD批量处理结构化标记, 实测占整体耗时的35%-50%。第二阶段虽然存在分支, 但通过预先生成的位图减少了50%以上的冗余判断。

关键优化技术对比

优化手段 传统方案 (ns/op) SIMD优化后 (ns/op) 加速比
引号匹配 82 19 4.3x
数字解析 67 28 2.4x
转义字符处理 113 105 1.1x
整体解析 420 155 2.7x

测试数据: 100KB嵌套JSON, Ice Lake平台

突破分支限制的实践
在必须保留分支的场景下, 通过掩码运算重构逻辑:

1
2
3
4
5
6
7
// 传统分支写法
if (ch == '"') { in_string = !in_string; }

// SIMD友好改写
const __m512i quote = _mm512_set1_epi8('"');
__mmask64 mask = _mm512_cmpeq_epi8_mask(input, quote);
in_string ^= (mask >> bit_offset) & 0x1; // 位运算代替分支

这种方法在解析10万级键值对时, 分支预测失败率从18%降至3.7%。

混合架构的价值
simdjson等领先解析器的设计启示:

  1. 分层处理: SIMD负责结构扫描, 标量代码处理业务逻辑
  2. 内存优化: 通过位图记录结构偏移, 避免二次扫描
  3. 并行试探: 对数值类型预转换, 失败时回退到稳健解析
1
2
3
解析流水线示例:
原始字节 → SIMD标记层 → 结构位图 → 类型推测 → 最终DOM树
(3.8 cycles/byte) (分支密集) (内存敏感)

取舍的艺术
SIMD在JSON解析中的实践证明了工程优化的典型特征: 在局部热点上集中火力。当某个子任务满足以下特征时, 就值得尝试SIMD加速:

  1. 数据处理量占比 >20%
  2. 可转换为位/掩码操作
  3. 能通过预计算减少后续工作

这种针对性优化使得现代解析器在保持通用性的同时, 性能逼近手动编写的二进制协议解析器, 为数据密集型应用提供了重要助力。

Protobuf相关知识

protobuf是一种将结构化数据序列化的机制, 可用于内部设备通信或存储. 与JSON格式相比, 基于protobuf协议的二进制文件体积更小, 解析速度更快.

protobuf简介

类型

类型 解释
float, double 浮点数
int32, int64, uint32, uint64 整数,但不适合编码较大的数字和负数
sint32, sint64 针对负数进行优化的整数类型
fixed32, fixed64, sfixed32, sfixed64 更适合大数字的有符号数或无符号数
bool 布尔值
string 任意的UTF-8字符串
byte 任意的字节

protobuf对数字存储进行了优化,一个数字越小则存储长度越短。由于计算机使用补码表示负数,因此通常情况下负数将使用多个字节表示。为了优化这种情况,sint类型使用交叉的方式表示,绝对值较小的负数依然可以获得较短的存储长度。

protobuf命名冲突解决方案

对于PB的namespace, 规范要求每个PB都是全局唯一的. 如果设计不合理就会导致PB名称冲突, 对于高版本的依赖库, Go语言在启动时会直接painc, 导致系统无法启动.

对于上述问题, 可以通过降级依赖版本临时解决:

1
2
3
4
replace (
github.com/golang/protobuf => github.com/golang/protobuf v1.4.3
google.golang.org/protobuf => google.golang.org/protobuf v1.25.0
)

有趣的项目推荐

Github使用

免费开发环境

每月可免费使用120核心小时的服务器资源. 停止运行后, 不计算核心小时资源, 仅计算存储资源.

默认启用2核心服务器, 可使用60小时, 平均每天可使用2小时. 30min无操作自动关闭, 几乎等于无限制使用.

Calibre优化

书籍样式修改

对于EPUB格式的数据, 实际上就是压缩格式的HTML代码, 因此可以使用HTML的技术进行修改, 例如调整文字行间距, 可使用属性

1
<p style="line-height:1.5;">

将行间距调整为1.5倍

机器学习

大模型提示词

  • 赛博人格分裂,(启动人格分裂讨论模式+问题)
  • 阴阳怪气模式,(问题+笑死)毒舌属性
  • 触发预判模式,假设性问题(如果,,,会不会,,,)
  • 预言家模式,预判未来(如果,,,会发生什么)
  • 灵魂拷问模式,(①启动杠精模式②先写方案,再模拟杠精从*个角度狂喷,最后给出V2版方案),
  • 玄学编程(,,,带点蝉意)
  • 驯服转业话痨,(说人话!)
  • 人设粘贴术,
  • 启动老板思维(如果你是,,,你会怎么骂这个方案)
  • 过滤废话,(问题,+删掉所有正确的废话,只留能落地的建议)

高性能服务设计原则

高并发原则

无状态:
拆分:
服务化
消息队列
缓存:

高可用原则

降级:
限流
切流量
可回滚

最后更新: 2025年04月20日 21:28

版权声明:本文为原创文章,转载请注明出处

原始链接: https://lizec.top/2010/01/01/%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E5%BA%93%E4%B9%8B%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%8A%80%E6%9C%AF/