在我的代码库中有几个地方,对于大型数据集,相同的操作重复了很多次.在某些情况下,处理这些需要相当长的时间.
我相信使用SSE来实现这些循环应该会显着提高它们的性能,特别是在对同一组数据执行许多操作的情况下,所以一旦数据最初被读入缓存,就不应该有任何缓存未命中它.但是,我不确定是否会这样做.
是否有编译器和OS独立的方式编写代码以利用SSE指令?我喜欢VC++内在函数,其中包括SSE操作,但我还没有找到任何交叉编译器解决方案.
我仍然需要支持一些没有或有限SSE支持的CPU(例如Intel Celeron).有没有办法避免不得不制作不同版本的程序,比如有一种"运行时链接器"链接在基本或SSE优化代码基于运行进程时运行它的CPU?
那么其他CPU扩展怎么样,看看各种Intel和AMD CPU的指令集,其中有几个?
我最近注意到了
_m128 m = _mm_set_ps(0,1,2,3);
Run Code Online (Sandbox Code Playgroud)
在转换为float数组时,将4个浮点数置于相反的顺序:
(float*) p = (float*)(&m);
// p[0] == 3
// p[1] == 2
// p[2] == 1
// p[3] == 0
Run Code Online (Sandbox Code Playgroud)
同样的情况union { _m128 m; float[4] a; }也发生了.
为什么SSE操作使用这种排序?这不是什么大问题,但有点令人困惑.
还有一个后续问题:
通过索引访问数组中的元素时,是应该按顺序访问0..3还是按顺序访问3..0?
我使用SlimDX用C#编写的3D图形软件在CPU上进行了大量的矢量操作.(在这种特定情况下,无法将工作卸载到GPU).
如何让矢量数学更快?到目前为止,我发现了这些方法:
还有其他选项可以在.NET中实现更快的矢量数学吗?
有谁知道为什么GCC/Clang不会在下面的代码示例中优化函数test1,只是在使用fast-math选项时只使用RCPPS指令?是否有另一个编译器标志会生成此代码?
typedef float float4 __attribute__((vector_size(16)));
float4 test1(float4 v)
{
return 1.0f / v;
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处查看已编译的输出:https://goo.gl/jXsqat
我正在运行一些使用的C#代码,System.Numerics.Vector<T>但据我所知,我没有得到SIMD内在函数的全部好处.我正在使用Visual Studio Community 2015和Update 1,而我的clrjit.dll是v4.6.1063.1.
我正在使用英特尔酷睿i5-3337U处理器,它实现了AVX指令集扩展.因此,我想,我应该能够在256位寄存器上执行大多数SIMD指令.例如,拆卸中应包含的指令vmovups,vmovupd,vaddups,等...,并且Vector<float>.Count应该返回8,Vector<double>.Count应该是4,等等......但是,这不是我所看到的.
相反,我的拆卸包含指令等movups,movupd,addups等...以下代码:
WriteLine($"{Vector<byte>.Count} bytes per operation");
WriteLine($"{Vector<float>.Count} floats per operation");
WriteLine($"{Vector<int>.Count} ints per operation");
WriteLine($"{Vector<double>.Count} doubles per operation");
Run Code Online (Sandbox Code Playgroud)
生产:
16 bytes per operation
4 floats per operation
4 ints per operation
2 doubles per operation
Run Code Online (Sandbox Code Playgroud)
我哪里错了?要查看所有项目设置等,可在此处获得该项目.
我先说我是 SIMD 内在函数的完全初学者。
本质上,我有一个支持 AVX2 内在 ( Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz)的 CPU 。我想知道计算两个std::vector<float>size的点积的最快方法512。
我在网上做了一些挖掘,发现了这个和这个,这个堆栈溢出问题建议使用以下函数__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);,但是,这些都表明了执行点积的不同方法我不确定什么是正确的(和最快的)方法它。
特别是,我正在寻找对大小为 512 的向量执行点积的最快方法(因为我知道向量大小会影响实现)。
感谢您的帮助
编辑 1:我也对-mavx2gcc 标志有点困惑。如果我使用这些 AVX2 函数,我编译时是否需要添加标志?另外,-OFast如果我编写了一个天真的点积实现,gcc 是否能够为我做这些优化(比如我使用gcc 标志)?
编辑 2 如果有人有时间和精力,如果您能编写完整的实现,我将不胜感激。我相信其他初学者也会重视这些信息。
更新:请阅读代码,它不是关于计算一个int中的位
是否有可能通过一些聪明的汇编程序来提高以下代码的性能?
uint bit_counter[64];
void Count(uint64 bits) {
bit_counter[0] += (bits >> 0) & 1;
bit_counter[1] += (bits >> 1) & 1;
// ..
bit_counter[63] += (bits >> 63) & 1;
}
Run Code Online (Sandbox Code Playgroud)
Count 是在我算法的最内层循环中.
更新: 架构:x86-64,Sandy Bridge,因此可以使用SSE4.2,AVX1和旧技术,但不能使用AVX2或BMI1/2.
bits 变量几乎是随机位(接近半零和一半)
我需要一些澄清.我正在我的笔记本电脑上运行OpenCL,运行一个小型的nvidia GPU(310M).当我查询设备时CL_DEVICE_MAX_COMPUTE_UNITS,结果是2.我读取运行内核的工作组数量应该与计算单元的数量相对应(使用OpenCL进行异构计算,第9章,第186页),否则会浪费全球记忆力很强.
此外,芯片被指定具有16个cuda核心(对应于我认为的PE).这在理论上是否意味着,对于全局内存带宽,此gpu的最高性能设置是有两个工作组,每个工作项有16个工作项?
我正在尝试在霓虹灯中实现直方图.矢量化是否可能?
我在网络和英特尔软件手册上搜索过.但我无法确认所有英特尔64架构是否支持SSSE3或SSE4.1或SSE4.2或AVX等.因此,我可以在程序中使用最少的SIMD支持指令.请帮忙.