当前位置: 首页 > news >正文

Postgresql源码(149)SIMD应用与性能测试

1 SIMD指令集在PostgreSQL中的应用详解

SIMD是一种能够同时处理多个数据元素的CPU指令集技术,通过向量寄存器实现单条指令对多个数据的操作,可显著提高计算密集型任务性能。

SIMD在PG中主要应用于x86和ARM架构的CPU,针对事务ID数组的线性搜索、JSON字符串处理以及子事务搜索等场景进行了优化,性能提升可达20%以上 。

在这里插入图片描述

PostgreSQL中SIMD的应用场景

确定某个事务ID是不是InProgress状态。

bool
TransactionIdIsInProgress(TransactionId xid)
{......if (!TransactionIdEquals(topxid, xid) &&pg_lfind32(topxid, xids, nxids))return true;cachedXidIsNotInProgress = xid;return false;
}	

确定某个xid是不是在快照的xip或subxip数组中(运行中的事务)

bool
XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
{/* Any xid < xmin is not in-progress */if (TransactionIdPrecedes(xid, snapshot->xmin))return false;/* Any xid >= xmax is in-progress */if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))return true;if (!snapshot->takenDuringRecovery){if (!snapshot->suboverflowed){/* we have full data, so search subxip */if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt))return true;......
}

2 SIMD在PostgreSQL中的具体实现

pg_lfind8

bool
lfind8(uint8 key, uint8 *base, uint32 nelem)
{uint32		i;/* round down to multiple of vector length */

SIMD向量化处理,下面这行代码将数组长度向下舍入到向量长度(16字节__m128i)的倍数:

	uint32		tail_idx = nelem & ~(sizeof(Vector8) - 1);Vector8		chunk;

一次操作可以同时比较16个,不逐个比较

	for (i = 0; i < tail_idx; i += sizeof(Vector8)){vector8_load(&chunk, &base[i]);if (vector8_has(chunk, key))return true;}/* Process the remaining elements one at a time. */for (; i < nelem; i++){if (key == base[i])return true;}return false;
}

pg_lfind32

bool
pg_lfind32(uint32 key, uint32 *base, uint32 nelem)
{uint32		i = 0;
  • keys=vector32_broadcast:将要查找的key值广播到整个向量中(比如把5变成[5,5,5,5])
  • nelem_per_vector: 每个向量能容纳多少个uint32,4个!
  • nelem_per_iteration: 每轮 处理的元素数,16个!
	const Vector32 keys = vector32_broadcast(key);	/* load copies of key */const uint32 nelem_per_vector = sizeof(Vector32) / sizeof(uint32);const uint32 nelem_per_iteration = 4 * nelem_per_vector;

计算每轮处理范围:

将总元素数向下舍入到16的倍数,如果有100个元素,tail_idx = 96(6×16)

	/* round down to multiple of elements per iteration */const uint32 tail_idx = nelem & ~(nelem_per_iteration - 1);for (i = 0; i < tail_idx; i += nelem_per_iteration){Vector32	vals1,    // 存储数据的4个向量vals2,vals3,vals4,result1,  // 存储比较结果的4个向result2,result3,result4,tmp1,     // 临时合并向量 tmp2,result;   // 最终结果向量

一次vector32_load加载4个uint32到vals1中,共四次,共加载16个uint32进行计算。

		/* load the next block into 4 registers */vector32_load(&vals1, &base[i]);vector32_load(&vals2, &base[i + nelem_per_vector]);vector32_load(&vals3, &base[i + nelem_per_vector * 2]);vector32_load(&vals4, &base[i + nelem_per_vector * 3]);

计算

		/* compare each value to the key */result1 = vector32_eq(keys, vals1);result2 = vector32_eq(keys, vals2);result3 = vector32_eq(keys, vals3);result4 = vector32_eq(keys, vals4);/* combine the results into a single variable */tmp1 = vector32_or(result1, result2);tmp2 = vector32_or(result3, result4);result = vector32_or(tmp1, tmp2);/* see if there was a match */if (vector32_is_highbit_set(result))return true;}

处理不能被16整除的剩余元素

	/* Process the remaining elements one at a time. */for (; i < nelem; i++)if (key == base[i])return true;return false;
}

3 PG SIMD X86性能测试

https://github.com/mingjiegao/libsimd/tree/main

执行make check后,会自动做性能对比,结果如下:

=== Performance Tests ===
libsimd Performance Tests
=========================
System Information:
- Compiler: 8.5.0 20210514 (Tencent 8.5.0-26)
- AVX2 support: Enabled
- SSE4.2 support: EnabledPerformance Test Results
========================
Test Configuration:
- Iterations per test: 1000
- Warmup runs: 10
- Key distribution: 75% existing, 25% non-existingTest Name            |     Size |  SIMD (ms) | Linear (ms) |  Speedup | Status
--------------------------------------------------------------------------------
lfind8_small         |    10000 |       0.03 |       0.10 |     3.92x | PASS
lfind8_medium        |   100000 |       0.03 |       0.10 |     4.16x | PASS
lfind8_large         |  1000000 |       0.03 |       0.11 |     4.08x | PASS
lfind8_xlarge        | 10000000 |       0.03 |       0.10 |     3.96x | PASS
lfind32_small        |    10000 |       0.67 |       2.06 |     3.06x | PASS
lfind32_medium       |   100000 |       6.73 |      20.72 |     3.08x | PASS
lfind32_large        |  1000000 |     102.91 |     209.44 |     2.04x | PASS
lfind32_xlarge       | 10000000 |    1986.14 |    3120.74 |     1.57x | PASS
--------------------------------------------------------------------------------Performance Summary:
- Total tests: 8
- Passed tests: 8
- Failed tests: 0
- Average speedup: 3.23x
- SIMD implementation is 3.23x faster on averageNotes:
- Speedup values > 1.0 indicate SIMD is faster
- Results may vary based on CPU architecture and compiler optimizations
- All tests include correctness verificationWorst Case Performance Analysis
===============================
Worst case (key not found):
- SIMD time: 0.45 ms
- Linear time: 7.01 ms
- Speedup: 15.68xPerformance testing completed.
http://www.dtcms.com/a/446486.html

相关文章:

  • 知名网站建设加盟合作wordpress 腾讯视频插件下载
  • 重庆知名网站建设公司怎么去推广自己的网站
  • 深入 Pytest:用 Fixture 解锁高效 Python 测试之道
  • 一般做个网站需要多少钱建立网站需要做什么
  • Linux内核进程管理子系统有什么第六十二回 —— 进程主结构详解(58)
  • 博客系统-性能测试报告
  • 英文网站建设技术怎么建立博客网站
  • LangChain入门实践3:PromptTemplate提示词模板详解
  • 9.Spring ai alibaba 运维助手实战
  • 网站编写流程wordpress云采集
  • 找人建个网站多少钱淘宝客如何做免费的网站
  • maven-setting配置
  • 软件测试 —— B / 测试用例
  • 建设一个货架网站网站展示型和营销型有什么区别
  • 购物类网站的设计特点网站 二级分类
  • 做商城网站设计wordpress 作者墙
  • 哈希表封装实现unordered_set unordered_map
  • 网站开发的可行性报告有没有做那个的视频网站
  • RNN基础:序列数据处理与RNN原理(附Python代码)
  • 西安网站建设哪家强怎么做网站优
  • PHP文件与本地及外部资源的深度交互指南
  • Go基础:用Go语言操作redis详解
  • 网站切图怎么切一家三口的室内设计方案
  • AI面试经历与公司情况和职业发展分析与建议
  • 一个网站建设哪家快上海市普陀区建设规划局网站
  • HTTP相关
  • 【代码随想录day 35】 力扣 01背包问题 一维
  • 湖南网站开发公司电话江门网站
  • 适用于自动化脚本的PDF查看器?
  • 高校网站首页设计wordpress 自动保存