Elasticsearch:FMA 风格的向量相似度计算

作者:Chris Hegarty

在 Lucene 9.7.0 中,我们添加了利用 SIMD 指令执行向量相似性计算的数据并行化的支持。 现在,我们通过使用融合乘加 (Fused Mulitply-Add - FMA) 进一步推动这一点。

什么是 FMA

乘法和加法是一种常见的运算,它计算两个数字的乘积并将该乘积与第三个数字相加。 这些类型的操作在向量相似度计算期间反复执行。

融合乘加 (FMA) 是一种单一运算,可同时执行乘法和加法运算 - 乘法和加法被称为“融合”在一起。 FMA 通常比单独的乘法和加法更快,因为大多数 CPU 将其建模为单个指令。

FMA 还可以产生更准确的结果。 浮点数的单独乘法和加法运算有两轮; 一个用于乘法,一个用于加法,因为它们是单独的指令,需要产生单独的结果。 也就是说有效地表述为:

而 FMA 具有单舍入,仅适用于乘法和加法的组合结果。 也就是说有效地表述为:

在 FMA 指令中,a * b 生成无限精度的中间结果,在最终结果舍入之前将其与 c 相加。 与单独的乘法和加法运算相比,这消除了单轮运算,从而提高了准确性。

底层是如何实现的?

那么到底发生了什么变化呢? 在 Lucene 中,我们用单个 FMA 运算替换了单独的乘法和加法运算。 标量变体现在使用 Math::fma,而巴拿马向量化变体使用 FloatVector::fma。

如果我们查看反汇编,我们可以看到此更改所产生的效果。 之前我们看到过点积的巴拿马向量化实现的这种代码模式。

vmovdqu32 zmm0,ZMMWORD PTR [rcx+r10*4+0x10]
vmulps zmm0,zmm0,ZMMWORD PTR [rdx+r10*4+0x10]
vaddps zmm4,zmm4,zmm0

vmovdqu32 指令将 512 位打包双字值从内存位置加载到 zmm0 寄存器中。 然后,vmulps 指令将 zmm0 中的值与内存位置中相应的打包值相乘,并将结果存储在 zmm0 中。 最后,vaddps 指令将 zmm0 中的 16 个打包单精度浮点值与 zmm4 中的相应值相加,并将结果存储到 zmm4 中。

通过更改使用 FloatVector::fma,我们看到以下模式:

vmovdqu32 zmm0,ZMMWORD PTR [rdx+r11*4+0xd0]
vfmadd231ps zmm4,zmm0,ZMMWORD PTR [rcx+r11*4+0xd0]

同样,第一条指令与前面的示例类似,它将 512 位打包双字值从内存位置加载到 zmm0 寄存器中。 vfmadd231ps(这是 FMA 指令)将 zmm0 中的值与内存位置中相应的打包值相乘,将中间结果添加到 zmm4 中的值,执行舍入并将生成的 16 个打包单精度浮点值存储在 zmm4.

vfmadd231ps 指令做了很多事情! 这是向 CPU 发出的关于代码正在运行的计算性质的明确信号。 鉴于此,CPU 可以就如何完成此操作做出更明智的决策,这通常会提高性能(以及前面所述的准确性)。

这样的修改会快吗?

一般来说,使用 FMA 通常会提高性能。 但一如既往,你需要进行基准测试! 值得庆幸的是,Lucene 在确定是否使用 FMA 时会处理相当复杂的问题,因此你不必这样做。 例如,CPU 是否支持 FMA、Java 虚拟机中是否启用了 FMA,以及仅在已证明比单独的乘法和加法运算更快的架构上启用 FMA。 正如你可能知道的那样,这种启发式方法并不完美,但对于提供良好的开箱即用体验大有帮助。 虽然 FMA 提高了准确性,但我们发现在未启用 FMA 时对预先存在的相似性计算没有负面影响。

随着 FMA 的使用,向量相似性函数套件得到了一些(更多)的喜爱。 所有点积、平方和余弦距离、标量和巴拿马向量化变体均已更新。 基于反汇编检查和实证实验进行了优化,带来了有助于填充管道并保持 CPU 繁忙的改进; 主要是通过更加一致和有针对性的循环展开,以及消除循环内的数据依赖性。

在此更改上给出具体的性能改进数字并不简单,因为效果涵盖了多个相似函数和变体,但我们看到了积极的吞吐量改进,从浮点点积中的个位数百分比到余弦中更高的两位数百分比改进。 基于字节的相似性函数也显示出类似的吞吐量改进。

总结起来

在 Lucene 9.7.0 中,我们添加了通过 SIMD 指令更快地实现向量搜索所使用的低级原语操作的功能。 在即将推出的 Lucene 9.9.0 中,我们在此基础上利用更快的 FMA 指令,并在所有相似性函数中更一致地应用优化技术。 以前版本的 Elasticsearch 已经受益于 SIMD,即将推出的 Elasticsearch 8.12.0 将具有 FMA 改进。

最后,我想感谢 Lucene PMC 成员 Robert Muir 在这一领域的持续改进,以及愉快而富有成效的合作。

原文:Vector Similarity Computations FMA-style — Elastic Search Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/159391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

作品Demo:大全

实用小demo 1.3D-地图工程 获取连接:nullhttps://m.tb.cn/h.5kzPTgJ?tkRPBlWep4ZIf 2.3D-饼图 获取连接:https://m.tb.cn/h.5Pt4A8k?tkXRzWWepUnu4https://m.tb.cn/h.5Pt4A8k?tkXRzWWepUnu4

一个月B站涨粉200万,品牌号不可错过的吸粉秘籍

越来越多品牌为了持续在B站营销而创建品牌官方账号,发布原创作品融入B站UP主中,吸引B站用户塑造品牌形象,提高品牌传播度、品牌声量。 据飞瓜数据(B站版)统计,B站有着超过2万个品牌号,本篇文章…

亚马逊买家号用邮箱怎么注册

想要用邮箱注册亚马逊买家号,那么准备好能接受验证码的邮箱后打开相应的亚马逊官网即可。打开官网后点击注册——输入昵称——输入邮箱——输入密码——接受邮箱验证码并输入,如果遇到需要手机号验证就输入手机号,如果不需要验证,…

7.Gin 路由详解 - 路由分组 - 路由文件抽离

7.Gin 路由详解 - 路由分组 - 路由文件抽离 前言 在前面的示例中,我们直接将路由的定义全部写在 main.go 文件中,如果后面 路由越来越多,那将会越来越不好管理。 所以,下一步我们应该考虑将路由进行分组管理,并且将其抽…

剧情继续:马斯克曝出OpenAI前员工举报信,董事会与奥特曼谈判回归

丰色 发自 凹非寺 量子位 | 公众号QbitAI 经过4天的极限拉扯、反转再反转,奥特曼有可能重新回归了。 据知情人士透露,OpenAI董事会正与奥特曼进行一场“富有成效”的新谈判。 如果奥特曼回到OpenAI,他将继续担任CEO。 与此同时&#xff0c…

【开源】基于JAVA的音乐偏好度推荐系统

项目编号: S 012 ,文末获取源码。 \color{red}{项目编号:S012,文末获取源码。} 项目编号:S012,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.1.1 音乐档案模块2.1…

Unsupervised Condition GAN

Unsupervised Condition GAN主要有两种做法: Direct Transformation 直接输入domain X图片,经过Generator后生成对应的domain Y的图像。这种转化input和output不能够差太多。通常只能实现较小的转化,比如改变颜色等。 Projection to Commo…

【C++】:STL中的string类的增删查改的底层模拟实现

本篇博客仅仅实现存储字符(串)的string 同时由于Cstring库设计的不合理,我仅实现一些最常见的增删查改接口 接下来给出的接口都是基于以下框架: private:char* _str;//思考如何不用constsize_t _size;size_t _capacity;//这样写可以const static size_t…

【Windows 常用工具系列 13 -- Confluence 如何快速输入代码块 code block】

文章目录 Confluence 如何快速输入代码块方法二 Confluence 如何快速输入代码块 在使用使用 confluence 进行文档编辑时,有时需要贴上部分代码,但是直接贴代码在 confluence上,显示效果不是太好看,所以confluence 给我们提供了符…

SpringBoot启动后自动打开浏览器访问项目

更简单的一个方法 Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " url); Springboot项目启动后自动打开浏览器访问(超实用)_浏览器访问springboot项目-CSDN博客 Springboot项目启动后自动打开浏览器访问 1、在Springboot项目中每次启动完项…

PostgreSQL (Hologres) 日期生成

PostgreSQL 生成指定日期下一个月的日期 (在Hologres中,不支持递归查询) SELECTto_char(T, YYYYMMDD)::int4 AS date_int,date(T) AS date_str,date_part(year, T)::int4 AS year_int,date_part(month, T)::int4 AS month_int,date_part(da…

1.8w 字详解 SQL 优化

来源:捡田螺的小男孩 1、MySQL的基本架构 2、SQL优化 3、explain执行计划常用关键字详解 很多朋友在做数据分析时,分析两分钟,跑数两小时? 在使用SQL过程中不仅要关注数据结果,同样要注意SQL语句的执行效率。 本文…

国内怎么投资黄金,炒黄金有哪些好方法?

随着我国综合实力的不断强大,投资市场的发展也日臻完善,现已成为了国际黄金市场的重要组成部分,人们想要精准判断金市走向,就离不开对我国经济等信息的仔细分析。而想要有效提升盈利概率,人们还需要掌握国内黄金投资的…

用css实现原生form中radio单选框和input输入框的hover样式以及聚焦focus的样式

一.问题描述:用css实现原生form中radio单选框和input的hover已经focus的样式 在实际的开发中,一般公司ui都会给效果图,比如单选按钮radio样式,input输入框hover的时候样式,以及focus的时候样式,等等&#…

Ubuntu安装PCAN-View

目录 一. Hardware 二. Software 2.1 安装驱动 2.2 安装PCAN-View QA 本文介绍如何安装linux版的PCAN-View。 PCAN-View:用来抓包分析CAN/CANFD报文。Hardware: PEAK-System Linux generic #37~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Oct 9 15:34:04 UTC 2…

Java 最简单的实现 AES 加密和解密

AES简介 AES(Advanced Encryption Standard)高级加密标准,是一种被广泛使用的对称加密算法,用于加密和解密数据。它曾经是美国政府的一个机密标准,但现在已成为公开的加密算法,并被广泛使用于商业、政府及…

第四代智能井盖传感器:智能井盖位移监测

当城市道路上的井盖出现异常时,可能会导致突发的交通事故或人员受伤事件。而传统的井盖监测往往依靠人力进行巡查,这种方式可能会因为监测不及时或不准确而带来问题。但是现在有了智能井盖传感器,它们成为了城市地下生命线的守护者。这种智能…

【开源】基于Vue.js的开放实验室管理系统的设计和实现

项目编号: S 013 ,文末获取源码。 \color{red}{项目编号:S013,文末获取源码。} 项目编号:S013,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…

净利降4成、股价腰斩,戎美困在“淘系女装第一股”

今年的“双11”静悄悄。 作为“淘系女装第一股”,戎美却拒绝参加“双11”。 戎美作为一家淘宝女装店,喊出“从不打折,从不参加任何促销”的口号;尽管戎美采取独特的营销策略,但其业绩承压困局也写在最新的三季报里。…