SSE加速随笔
Intel® Intrinsics Guide
搞懂SSE

寄存器与指令数据细节
SSE指令集推出时,Intel公司在Pentium III CPU中增加了8个128位的SSE指令专用寄存器,称作XMM0到XMM7。这些XMM寄存器用于4个单精度浮点数运算的SIMD执行,并可以与MMX整数运算或x87浮点运算混合执行。
2001年在Pentium 4上引入了SSE2技术,进一步扩展了指令集,使得XMM寄存器上可以执行8/16/32位宽的整数SIMD运算或双精度浮点数的SIMD运算。对整型数据的支持使得所有的MMX指令都是多余的了,同时也避免了占用浮点数寄存器。SSE2为了更好地利用高速寄存器,还新增加了几条寄存指令,允许程序员控制已经寄存过的数据。这使得 SIMD技术基本完善。
SSE3指令集扩展的指令包含寄存器的局部位之间的运算,例如高位和低位之间的加减运算;浮点数到整数的转换,以及对超线程技术的支持。
AVX是Intel的SSE延伸架构,把寄存器XMM 128bit提升至YMM 256bit,以增加一倍的运算效率。

数据结构
由于通常没有内建的128bit和256bit数据类型,SIMD指令使用自己构建的数据类型,这些类型以union实现,这些数据类型可以称作向量,一般来说,MMX指令是__m64 类型的数据,SSE是__m128类型的数据等等

- 每一种类型,从2个下划线开头,接一个m,然后是向量的位长度。
- 如果向量类型是以d结束的,那么向量里面是double类型的数字。如果没有后缀,就代表向量只包含float类型的数字。
- 整形的向量可以包含各种类型的整形数,例如char,short,unsigned long long。也就是说,__m256i可以包含32个char,16个short类型,8个int类型,4个long类型。这些整形数可以是有符号类型也可以是无符号类型
内存对齐
为了方便CPU用指令对内存进行访问,通常要求某种类型对象的地址必须是某个值K(通常是2、4或8)的倍数,如果一个变量的内存地址正好位于它长度的整数倍,我们就称他是自然对齐的。
通常对于各种类型的对齐规则如下:
数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
联合 :按其包含的长度最大的数据类型对齐。
结构体: 结构体中每个数据类型都要对齐
对于SIMD的内存对齐是指__m128等union在内存中存储时的存储方式。
对于各成员变量来说,存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数,各成员变量在存放的时候根据在结构中出现的顺序依次申请空间, 同时按照上面的对齐方式调整位置, 空缺的字节自动填充。
对于整个结构体来说,为了确保结构的大小为结构的字节边界数(即该结构中占用最大的空间的类型的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
intel官网
https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
解决报错
SSE采用“接-化-发”原理
寄存器接收
__m128i _mm_loadu_si128 (__m128i const* mem_addr)
处理转化
__m128i _mm_cvtepu8_epi16 (__m128i a)
__m256i _mm256_sub_epi16 (__m256i a, __m256i b)
......
发送出去
void _mm256_storeu_si256 (__m256i * mem_addr, __m256i a)

项目总结

大佬说:这个正常情况下用一维的就可以了,有必要的时候才用2维的
大致意思是 公司一般用一维就够用了,因为二维的会多出来一个维度,公司的电脑是8核的 使用二维会增大好多计算量。 我理解 90%的情况是一维的

yr:我们目前好像都是用一维的 , 我们一般都是对 row分割 . 理由大概率是这个吧 所以一般tbb对于大图像的提速会好一点
加速时会消耗内存以提高速度 , 消耗内存就是空间换时间
算法分为空间复杂度和时间复杂度,一般在工作中时间要求更高,可以改变算法逻辑,必要情况下,哪怕提高空间复杂度也要降低时间复杂度
并发算法都是压榨设备的性能,特别是现在的多核处理器。但是如果设备性能不够高,即使很高的并发也实现不了,而且将串行修改成并行或者并发,都是要额外付出时间的,所以leader说没必要用二维度的range,就是因为公司电脑性能带不动二维,强行使用带不来较一维明显的效果,还压榨设备性能,也会造成硬件的加速老化。
实际项目中往往牺牲内存提升速度,通过开辟更大的内存,即扩大空间复杂度。来降低算法实现的时间复杂度 所以同样的效果其实可以有很多实现方式,而且优劣分明。
加速算法主要就是在空间复杂度和时间复杂度上下文章
电脑提速从而减少浪费内存
1、tbb和OpenMP都是多线程的无法结合进行加速,尝试结合后,时间迸发;
2、tbb加速比较实用的还是lambda表达式的形式;
3、OpenMP使用需要配置VS属性:
在项目上右键->属性->配置属性->C/C++->语言->OpenMP支持,选择“是”即可。提供指向 OpenMP API 中使用的构造的链接。
4、SSE支持的数据类型是4个32位(共计128位)浮点数集合,就是C、C++语言中的float[4],并且必须是以16位字节边界对齐的。因此这也给输入和输出带来了不少的麻烦,实际上主要影响SSE发挥性能的就是不停地对数据进行复制以适用应它的数据格式。
5、用AVX指令集必须做好合适的IDE配置。
在C/C++ ->代码生成的启用增强指令集里
+++++++++++++++++++++++++++++++++++++++++++++++++++
使用注意事项
该代码段使用Intel SSE (Streaming SIMD Extensions) 指令集进行图像处理。通过看代码,它似乎对图像中的每个像素执行一些操作,具体地,它似乎是对两张图像执行了某种差异检测。
以下是我观察到的一些问题及建议:
- 拼写错误:
-
- m_offest 应该是 m_offset。在 if (filterPtr[c] - srcPtr[c] <m_offest) 中确保变量名是正确的。
- 可能的内存对齐问题:
-
- 当使用 _mm_loadu_si128 时,它从非对齐的内存加载数据。对于最佳性能,如果您的数据是对齐的,使用 _mm_load_si128 会更快。但这取决于 m_srcImage.ptr<const uchar>(r) 返回的数据是否已经对齐。
- 越界访问:
-
- 在SSE循环中,确保您不会越过图像的尾部。(m_srcImage.cols) - 32 可能导致您在最后几列中丢失一些像素。但在您的代码中,之后的非SSE循环应该会处理这些,只要确保这两个循环之间没有重叠或遗漏。
- _x80 和 reg_offset 未定义:
-
- 代码中使用了 _x80 和 reg_offset,但没有给出其定义或赋值。这可能只是提供的代码片段的一部分,但确保这两个变量在上文中有正确的定义和初始化。
- 差异检测逻辑:
-
- SSE循环和非SSE循环似乎有不同的逻辑。在SSE部分,您首先对像素值执行XOR操作,并在减去之前比较它们。在非SSE部分,您只是直接减去它们。这两者可能不完全等价,除非 _x80 仅仅是一个将无符号字节转换为有符号字节的偏移量。
- 比较操作的逻辑:
-
- 在SSE部分,您使用了 _mm_cmplt_epi8,这会比较两个向量中的每个字节,并返回一个掩码,其中每个字节要么是 0xFF (如果a < b),要么是 0x00。这可能与非SSE部分中的逻辑不完全匹配,因为您在那里直接将值设置为 255 或 0。确保两者的逻辑是一致的。
总的来说,除了这些问题和考虑点外,代码似乎是为了性能优化而写的。确保在更改之后进行充分的测试,以确保您的修改不会引入新的问题或性能下降。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SSE部分和小于部分差异,防止
- 差异检测逻辑:
在使用SSE指令集进行图像处理时,保持一致性非常重要。下面是一种方法,可以使SSE循环和非SSE循环的逻辑保持一致。
差异检测逻辑的统一:
- 定义_x80的用途: _x80 应该是一个常量,其值是 128 (即 0x80 in hexadecimal),它用于将无符号整数转换为有符号整数,反之亦然。这样可以使得原本的 0..255 范围的无符号字节变为 -128..127 的有符号字节。
- 在非SSE循环中应用相同的转换: 为了使非SSE循环与SSE循环保持一致,您需要在处理之前将无符号字节转换为有符号字节。
修改后的非SSE循环部分可以是:

// 其他情况下,C小于32的时候处理
for (; c < m_srcImage.cols; c++)
{
//if (filterPtr[c] - srcPtr[c] <m_offest) //m_offest偏移量
// threshPtr[c] = 255;
//else
// threshPtr[c] = 0;
// 将像素值转换为有符号形式,与SSE部分保持一致// 将像素值转换为有符号形式,与SSE部分保持一致const char signed_src = static_cast<char>(srcPtr[c] ^ 0x80);const char signed_filter = static_cast<char>(filterPtr[c] ^ 0x80);// 使用有符号字节进行差值计算if (signed_filter - signed_src < static_cast<char>(m_offset))threshPtr[c] = 255;elsethreshPtr[c] = 0;
}
相关文章:
SSE加速随笔
Intel Intrinsics Guide 搞懂SSE 寄存器与指令数据细节 SSE指令集推出时,Intel公司在Pentium III CPU中增加了8个128位的SSE指令专用寄存器,称作XMM0到XMM7。这些XMM寄存器用于4个单精度浮点数运算的SIMD执行,并可以与MMX整数运算或x87浮点运…...
【TES720D】青翼科技基于复旦微的FMQL20S400全国产化ARM核心模
板卡概述 TES720D是一款基于上海复旦微电子FMQL20S400的全国产化核心模块。该核心模块将复旦微的FMQL20S400(兼容FMQL10S400)的最小系统集成在了一个50*70mm的核心板上,可以作为一个核心模块,进行功能性扩展,特别是用…...
arcgis删除细长图斑的方法
1、有一张图斑数据如下: 如上图,有很多细长的面要素,需要保留的仅是图中的块状要素。 2、首先要将被合并的要素进行拆分,具体拆分步骤如下: 将所有要素选中,点击高级编辑中的拆分按钮。 3、拆分后图斑就…...
Flutter笔记:Flutter的WidgetsBinding.instance的window属性
Flutter笔记 Flutter的WidgetsBinding.instance的window属性 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/det…...
element UI DatePicker 日期选择器 点击时间点可选限制范围前后十五天
<el-date-picker v-model"timeRange" type"datetimerange" align"right" :default-timedefaultTimevalue-format"yyyy-MM-dd HH:mm:dd" range-separator"至" start-placeholder"开始日期"end-placeholder"…...
【自用】vmware workstation建立主机window与虚拟机ubuntu之间的共享文件夹
1.在windows中建立1个文件夹 在vmware中设置为共享文件夹 参考博文: https://zhuanlan.zhihu.com/p/650638983 2.解决: (1)fuse: mountpoint is not empty (2)普通用户也能使用共享目录 参考博文&#x…...
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析 1 题目 坑洼道路检测和识别是一种计算机视觉任务,旨在通过数字图像(通常是地表坑洼图像)识别出存在坑洼的道路。这…...
Mozilla Firefox 119 现已可供下载
Mozilla Firefox 119 开源网络浏览器现在可以下载了,是时候先看看它的新功能和改进了。 Firefox 119 改进了 Firefox View 功能,现在可以提供更多内容,如最近关闭的标签页和浏览历史,你可以按日期或网站排序,还支持查…...
What is 哈希?
哈希 前言:大一大二就一直听说哈希哈希,但一直都没有真正的概念:What is 哈希?这篇博客就浅浅聊一下作者认知中的哈希。 理解哈希 哈希(Hash)也可以称作散列,实质就是一种映射…...
在Photoshop中如何校正倾斜的图片
在Photoshop中如何校正倾斜的图片呢?今天就教大家如何操作。 将需要操作的图片拉到PS软件中,自动形成项目。 点击上方“滤镜”中的“镜头校正”。 进入“镜头校正”窗口,点击左侧的“拉直工具”。文章源自设计学徒自学网-http://www.sx1c.co…...
Maven第六章:Maven的自定义插件开发
Maven第六章:Maven的自定义插件开发 前言 maven不仅仅只是项目的依赖管理工具,其强大的核心来源自丰富的插件,可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解,希望对各位读者有所帮助。 Maven插件开发的基本概念 Maven插件是由Maven构建工具本身…...
springboot 注入配置文件中的集合 List
在使用 springboot 开发时,例如你需要注入一个 url 白名单列表,你可能第一想到的写法是下面这样的: application.yml white.url-list:- /test/show1- /test/show2- /test/show3Slf4j RestController RequestMapping("/test") pub…...
springboot整合redis+lua实现getdel操作保证原子性
原始代码 脚本逻辑先获取redis的值,判断是否等于期望值。 条件成立则删除,不成立则返回0 if redis.call(get, KEYS[1]) ARGV[1] thenreturn redis.call(del, KEYS[1]) end return 0 测试代码 根据上面的逻辑加了测试, 在判断成功后等待5…...
win10系统nodejs的安装npm教程
1.在官网下载nodejs,https://nodejs.org/en 2,双击nodejs的安装包 3,点击 next 4,勾选I accpet the terms in…… 5,第4步点击next进入配置安装路径界面 6,点击next,选中Add to PATH ,旁边…...
C语言assert函数:什么是“assert”函数
我一直在学习 OpenCV 教程,遇到了assert函数;它做什么? assert将终止程序(通常带有引用 assert 语句的消息),如果其参数为 false。它通常在调试过程中使用,以使程序在发生意外情况时更明显地失败。 例如&…...
R语言绘图-5-条形图(修改坐标轴以及图例等)
0. 说明: 1. 绘制条形图; 2. 添加文本并调整位置; 3. 调整x轴刻度的字体、角度及颜色; 4. 在导出pdf时,如果没有字体,该怎么解决问题; 1. 结果: 2. 代码: library(ggp…...
uniapp自定义权限菜单,动态tabbar
已封装为组件,亲测4个菜单项目可以切换, 以下为示例,根据Storage 中 userType 的 值,判断权限菜单 <template><view class"tab-bar pb10"><view class"tabli" v-for"(tab, index) in ta…...
ubuntu20.04配置解压版mysql5.7
目录 1.创建mysql 用户组和用户2.下载 MySQL 5.7 解压版3.解压 MySQL 文件4.将 MySQL 移动到适当的目录5.更改mysql目录所属的用户组和用户,以及权限6.进入mysql/bin/目录,安装初始化7.编辑/etc/mysql/my.cnf配置文件8.启动 MySQL 服务:9.建立…...
【js】vue获取document.getElementById(a)为null
需求 在菜单A页面点击某个元素携带id跳转到B详情页面,B页面获取该id元素的offsetTop, 并自动滚动到该元素处 问题 跳转到B详情页面, 在mounted获取到document.getElementById(a)为null, 因为整个详情页面是从后端获取来渲染的数据, 因此此时dom元素还未渲染出来,…...
系列六、Mybatis的一级缓存
一、概述 Mybatis一级缓存的作用域是同一个SqlSession,在同一个SqlSession中执行两次相同的查询,第一次执行完毕后,Mybatis会将查询到的数据缓存起来(缓存到内存中), 第二次执行相同的查询时,会…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
