0

0

诡异的精度diff追查_PHP教程

php中文网

php中文网

发布时间:2016-07-12 09:01:35

|

1317人浏览过

|

来源于php中文网

原创

ImgGood
ImgGood

免费在线AI照片编辑器

下载

诡异的精度diff追查

一、query-diff测试发现的问题

Query-diff是检索端常用的测试方法,其思想是使用一组相同的检索信息分别请求一个系统或模块的基线版本和待测版本。通常,基线版本和待测版本只存在少量差异(程序功能/配置等)。发送请求后,比较两个版本返回的检索结果,从而验证差异是否对最终计算结果造成了影响。

诡异的精度diff追查_PHP教程

本case中的被测模块A由C++编写,输出的核心数据为一个单精度浮点数,记为Q。

在A模块某次升级后执行query-diff测试时,发现Q值存在精度diff,比例约为1%,最大diff在小数万分位,而该次升级预期是无diff的。

二、深入追查

通常出现diff,首先要明确追查的方向,如果一眼看不出原因,就需要使用排除法来逐个验证怀疑对象,缩小范围,减小不必要的精力投入。于是列出了两大排查方向:环境或程序。

先看环境:

l 在环境现场仔细检查了新旧环境的配置和词表,符合预期,排除了环境搭建工具的因素。

l 由于此次升级是前向兼容的,将新旧环境的配置和词表统一,重新测试,diff复现,排除了配置差异的因素。

环境似乎没有问题,再来验证程序:

l 因已做了多组测试,验证结果没有改变,排除了随机策略diff的可能。

l 打印debug日志,检查了处理过程中的每一步中间结果,均无问题,只在计算Q值的最后环节出现了diff,相继排除了线程脏数据,进程级cache脏数据,变量类型转换等风险点。

l 为彻底确认,直接将新旧环境里的程序都替换为新版本,重新测试,如果真是程序所致,应当无diff。然而,diff复现了!明明没有随机diff的啊?!!

此时排查到了瓶颈,环境和程序的原因似乎都不对。

冷静下来重新思考,之前的排查分别把环境的概念解释为使用的配置和词表,认为两者相同,环境就相同。这是片面的,环境的含义还应当包含系统和硬件的编译环境和运行环境。于是有了新的验证思路:

l 新旧版本的程序都使用公司的云编译集群产出,应当没有问题,不过为防止想当然,还是认真检查了编译参数并在本地相同机器重新编译了新旧版本,确认diff复现,排除编译因素;

l 将新旧环境拷贝到同一台机器,重压请求,diff消失!确认为运行环境因素

运行环境包括操作系统和硬件层面,趁热打铁,继续追查:

l 确认出现diff的两台机器操作系统一致,均为centos 4.3,排除了操作系统;

l 硬盘和内存的型号差异造成diff的可能性较小,暂不验证;

l 新环境所在机器cpu版本Xeon E5645,旧环境所在机器cpu版本 Xeon E5-2620,怀疑cpu型号不同所致,另找了一台与旧环境cpu一致的机器部署新环境,重新测试,diff消失,目标锁定cpu。

诡异的精度diff追查_PHP教程

二、揭开真相

分析cpu,在简单排除了核数,最大线程数,一二三级缓存的嫌疑后,cpu特性列表中的指令集差异引起了我的注意。
诡异的精度diff追查_PHP教程

补充知识一:cpu指令集的作用

指令集是存储在CPU内部,对CPU运算进行指导和优化的硬程序。拥有这些指令集,CPU就可以更高效地运行。为解释指令集的优化方式,得提到两种技术:SISD(单指令单数据)和SIMD(单指令多数据)。

以加法指令为例,使用SISD的CPU对加法指令译码后,执行部件先访问内存,取得第一个操作数,之后再一次访问内存,取得第二个操作数,后才能进行求和运算。而在使用SIMD的CPU中,指令译码后几个执行部件同时访问内存,一次性获得所有操作数进行运算。这个特点使SIMD特别适合于数据密集型运算。

Cpu指令集中的SSE系列和AVX用于浮点数运算,而AVX正是两个cpu的差异之一,嫌疑很大。现在需要找到程序使用AVX进行优化的证据。

可是,在ASQ模块中并没有直接优化的代码逻辑,涉及Q值计算的程序中虽然调用了静态libA的接口,而libA的代码也未使用指令集。不过,libA联编了静态libB,于是一路往底层追查,查到编译依赖的第四层,是IDL提供的libX,代码保密无法查看。

只好向相关RD请教,RD告知libX中确实使用了SSE指令优化,以及Intel提供的数学函数库MKL,却没有用到AVX。

诡异的精度diff追查_PHP教程

难道又是条走不通的死路?抱着最后一点希望,查询了MKL在intel官方的介绍发现意外收获,MKL中引入了AVX优化!【1】

诡异的精度diff追查_PHP教程


现在还差最后一步,得确认AVX就是diff来源的元凶。很快,在intel的产品手中找到了进一步的证据【2】:

诡异的精度diff追查_PHP教程

AVX2中的FMA指令,在矩阵乘法、点积、多项式评估等涉及浮点数运算方面的效率和精度相对以往的指令集都有所提升,因为FMA可以将乘法与累加操作一次性完成。官方论坛里也找到了相关技术人员的帖子佐证【3】:

诡异的精度diff追查_PHP教程

补充知识二:计算机中浮点数存储方式

float和double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。

无论是单精度还是双精度在存储中都分为三个部分:

1. 符号位(Sign) : 0代表正,1代表为负

2. 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储

3. 尾数部分(Mantissa):尾数部分

其中float的存储方式如下表所示:

总长度

尾数部分

指数部分

符号位

单精度

32bit

0-22

23-30

31

双精度

64bit

0-51

52-62

63

扩展双精度

80bit

0-63

64-78

79

硬件层面上,cpu的浮点运算逻辑都是放在FPU(浮点运算单元)上实现的(无论SSE还是AVX),FPU的默认计算精度是80bit,而SSE和AVX输出的float精度没那么高(均为32bit),如果FPU中计算精度存在差异(前提是均大于32bit),计算输出时截断为32bit再存入内存,必然会因近似截断造成结果diff。

由于intel底层算法保密,只能猜测AVX和SSE的优化函数实现时设置的FPU精度有所不同,但精度差异的结论是确定的。

此时真相已浮出水面:AVX的FMA相比SSE精度上多1bit,存在迭代计算时,差异将会累计。而Q值的产生经历复杂的矩阵运算,这个微小的1bit差异被放大至小数点万分位。同时,Intel保证了各机器的兼容性,MKL的代码在不支持AVX的cpu上运行时会被降级为SSE。

补充知识三:使用SSE和AVX优化程序的方法

仍以加法指令为例,对于相关头文件的引入和编译指令相关准备此处不进行介绍,可参考相关资料。

基本版:

简单地循环累加求和。

诡异的精度diff追查_PHP教程

SSE优化版

SSE寄存器128bit,16字节,一次可以存4个单精度浮点数,可以每4个一组存入寄存器,使用内置加法函数求和,之后再对4个分组和进行相加,最后加上分组剩余的几项,得到最终结果。

诡异的精度diff追查_PHP教程

AVX优化版

AVX优化方式与SSE类似,但AVX寄存器使用256bit,32字节,可以存8个单精度浮点数,需要每8个float一组存入寄存器。

诡异的精度diff追查_PHP教程

现在随机生成输入数组,撰写简单的测试用例,就可以验证优化的效果了,以下是三种算法的性能比较,单位为每秒可累加float的数量。结果中,SSE效率提升到普通版的4倍,而AVX是8倍!【4】

诡异的精度diff追查_PHP教程

二、总结和启示

问题总结:

l Query-diff兼容性测试时发现模块A新旧版本计算出的Q值存在diff;

l 排查后,确定精度diff来自程序因运行环境cpu支持的浮点数指令集差异(AVX/SSE)

l 该case中diff占比和绝对值均较小,目前虽不至影响线上服务,但若算法进一步复杂,diff积累至百分位,便会导致策略失效。

l 其他模块的浮点数运算若用到指令集优化,也需要排查是否相同问题。

解决方案:

l 分配测试资源时,保证新旧环境所在机器cpu一致;

l 执行query-diff前加入环境检查机制,再次确认硬件无差异;

l 线上部署服务时,也需要确定机器支持AVX指令集,达到性能和精度最优;

l 排查其他模块是否有类似使用指令集优化的情况,提前规避风险。

启发和建议:

l 浮点数运算密集型程序可考虑使用SSE/AVX等指令集函数优化性能,通常可显著提高运行效率(SSE:4倍,AVX:8倍);

l 使用指令集时注意控制迭代使用的次数(即将指令集函数的输出再次作为指令集函数的输入),避免精度diff累积到不容忽视的程度;

l 可以将query-diff测试应用到更多的兼容性测试场景中,如比较CPU,操作系统,基础库等底层系统和硬件差异对应用程序的影响。

软件工程离不开硬件的支持,编译、运行环境的差异都有可能造成服务性能的差别和最终计算结果的差别。此类问题,在开发、测试、上线各个阶段都需要特别注意。做一个“软硬结合”的程序员很重要!

参考资料:

【1】 https://software.intel.com/zh-cn/articles/whats-new-in-intel-mkl

【2】 https://software.intel.com/zh-cn/articles/intel-xeon-processor-e7-88004800-v3-product-family-technical-overview

【3】 https://software.intel.com/en-us/forums/topic/507004

【4】 http://www.cnblogs.com/zyl910/archive/2012/10/22/simdsumfloat.html

百度MTC是业界领先的移动应用测试服务平台,为广大开发者在移动应用测试中面临的成本、技术和效率问题提供解决方案。同时分享行业领先的百度技术,作者来自百度员工和业界领袖等。

>>如有问题,欢迎与我沟通

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1088920.htmlTechArticle诡异的精度diff追查 一、Query-diff测试发现的问题 Query-diff是检索端常用的测试方法,其思想是使用一组相同的检索信息分别请求一个系统或...

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

89

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

276

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

59

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

99

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

105

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

230

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

619

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

173

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 21.4万人学习

Java 教程
Java 教程

共578课时 | 82.1万人学习

Uniapp从零开始实现新闻资讯应用
Uniapp从零开始实现新闻资讯应用

共64课时 | 7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号