什么时候用SIMD,什么时候用SIMT?
本帖最后由 你有种再说一遍 于 2024-7-31 03:27 编辑SIMD为什么快?因为它内部有两组寄存器,是取指令和执行指令的并行.
SIMD指令集是CPU的,信号传输长度比显卡SIMT要短,时间要少.不过处理数据量却是SIMT更胜一筹.
在不需要处理数据任务时候,搬运数据最快就是DMA芯片,称为0拷贝,通过少量的CPU指令执行,之后CPU就可以做其他事情,直到CPU接受DMA回调从而使用内存.
而需要处理数据时,访问内存最快的是SIMD+数组模式,并且利用循环展开实现有效利用CPU的分支流水线功能.通过一次载入内置专用指令(交换,累加,相减等等)和多组数据同时输入,就能加速运算.
最重要是SIMD的寄存器是核心内的,你可以还可以通过多线程并行使用满性能.相比遍历获取加速效率有4-50倍提高,可谓吓死人的快,50秒任务变成1秒啊...
数组需要是对齐的数据结构,AVX128或者AVX256指令集,一次性接受4个int32,8个int32,或者对应的float和double长度.
而Point3d只有3个值啊?无法对齐,那么怎么办呢?因此我们需要将Point3d改为x[],y[],z[]的SOA结构.甚至你还会发现值数组比点集数组用来判断范围更优秀.
它有什么用呢?
例子一:SimdJson
查找一个文本中是否含有分号,它就会通过扩充一个比较数组[;;;;]然后和文本数组一次性四个/八个比较.大大减少了分支预测失败的回滚代价.
十亿行天文台数据挑战
https://www.cnblogs.com/InCerry/p/17964592/7-1brc-in-dotnet-even-faster-than-java-cpp
例子二:比较两个数组是否相同
https://www.cnblogs.com/InCerry/p/dotnet-compare-two-byte-arrays.html
例子二:矩阵
矩阵平移实际上就是坐标数组全部数字+n.
矩阵变换就是矩阵乘法,能够相互不干扰的流水线元素相乘再相加.
例子三:SimdLinq
c#7优化了大量的Linq,它通过判断typeof(int[])然后直接跑SIMD指令.Max,Min,Sum,Sub等等,已经是通用的不需要再处理了.
例子四:数据库
列式数据库ClickHouse有用SIMD.因为采用了并行处理机制,即使一个查询,也会用服务器一半的CPU去执行,所以不能支持高并发的使用场景,默认单查询使用CPU核数为服务器核数的一半.
行式数据库Mysql用B+树和页表二分法获取数据行,而不是SIMD遍历,这样令它支持高并发场景.
显卡:
SIMT只是比SIMD多了一个可以终止线程的功能,也就是存在分支时候,能够终止线程,这一切是硬件实现的,不要跟我说软件模拟.
假设这个场景:当游戏控制视口一直往左,那么SIMT就能先预测并计算后面的,但是突然往右,就需要break掉预测的线程了.
预测可能不止一帧,连后面好几帧都预测了,硬件的矩阵单元就是这么多起来的.这就是为什么需要提供运动速度,不提供的话,还预测个毛线.
那么cad上面哪里用到了这个了?
屏幕平移pan/缩放显示zoom/
可以说,集显都能完成,却要配合你的表演.
显卡还有一些碰撞检测算法可以像素级运行,甚至还有一些利用CUDA排序的库.
这些都是图形学方面的,而在AI上面使用显卡是不太需要这些分支预测的功能,这就是为什么说现在的大模型可以独立一套硬件出来.
相关参考:
循环展开提高性能:
https://www.cnblogs.com/zyl910/p/dotnet_simd_BenchmarkVector3.html
.NET7是如何优化Guid.Equals性能的:
https://www.dongchuanmin.com/net/4294.html
c#SIMD的三角函数:
https://blog.ladeak.net/posts/math-sin-simd
页:
[1]