我在程序中执行的常见操作是通过标量缩放矢量(V*s,例如[1,2,3,4]*2 == [2,4,6,8]).是否有SSE(或AVX)指令执行此操作,除了首先在向量中的每个位置加载标量(例如_mm_set_ps(2,2,2,2))然后乘以?
这就是我现在所做的:
__m128 _scalar = _mm_set_ps(s,s,s,s);
__m128 _result = _mm_mul_ps(_vector, _scalar);
Run Code Online (Sandbox Code Playgroud)
我正在寻找像......
__m128 _result = _mm_scale_ps(_vector, s);
Run Code Online (Sandbox Code Playgroud) 我试图通过SSE和AVX提高复制操作的性能:
#include <immintrin.h>
const int sz = 1024;
float *mas = (float *)_mm_malloc(sz*sizeof(float), 16);
float *tar = (float *)_mm_malloc(sz*sizeof(float), 16);
float a=0;
std::generate(mas, mas+sz, [&](){return ++a;});
const int nn = 1000;//Number of iteration in tester loops
std::chrono::time_point<std::chrono::system_clock> start1, end1, start2, end2, start3, end3;
//std::copy testing
start1 = std::chrono::system_clock::now();
for(int i=0; i<nn; ++i)
std::copy(mas, mas+sz, tar);
end1 = std::chrono::system_clock::now();
float elapsed1 = std::chrono::duration_cast<std::chrono::microseconds>(end1-start1).count();
//SSE-copy testing
start2 = std::chrono::system_clock::now();
for(int i=0; i<nn; ++i)
{
auto _mas = mas;
auto _tar = tar; …Run Code Online (Sandbox Code Playgroud) SSE2具有在单精度浮点数和32位整数之间转换向量的指令.
_mm_cvtps_epi32()_mm_cvtepi32_ps()但是没有双精度和64位整数的等价物.换句话说,他们失踪了:
_mm_cvtpd_epi64()_mm_cvtepi64_pd()似乎AVX也没有它们.
模拟这些内在函数的最有效方法是什么?
我正在移植SSE SIMD代码以使用256位AVX扩展,并且似乎找不到任何将混合/混洗/移动高128位和低128位的指令.
支持故事:
我真正想要的是VHADDPS/ _mm256_hadd_ps表现得像HADDPS/ _mm_hadd_ps,只有256个字.不幸的是,它就像是HADDPS对低字和高字独立行动的两次调用.
我最近以内在函数的形式使用了x86 SIMD指令(SSE1234).我发现令人沮丧的是,SSE ISA有几个简单的指令,只能用于浮点数或仅用于整数,但理论上它们应该同样适用于两者.例如,float和double向量都有指令从地址(movhps,movhpd)加载更高的64位128位向量,但是没有这样的整数向量指令.
我的问题:
在整数向量上使用浮点指令时是否有任何理由期望性能受到影响,例如使用movhps将数据加载到整数向量?
我写了几个测试来检查,但我认为他们的结果不可信.编写一个正确的测试来探索这些事情的所有极端情况真的很难,特别是在这里可能涉及指令调度时.
相关问题:
其他平凡相似的东西也有几个基本相同的指令.例如,我可以使用por,orps或orpd按位OR .任何人都可以解释这些附加说明的目的是什么?我想这可能与应用于每条指令的不同调度算法有关.
我刚才注意到WD Hillis的Connection-Machine的第一批语言之一是*Lisp,它是具有并行结构的Common Lisp的扩展.Connection-Machine是一台具有SIMD架构的大规模并行计算机,与现代GPU卡非常相似.
因此,我希望将*Lisp改编为GPGPU - 可能是nVidia CUDA,因为它是最先进的事实标准 - 非常自然.
到目前为止,除了用于C/C++的nVidia SDK之外,我还发现了Python环境PyCUDA.有没有人听说过Lisp?
我想添加一个SSE寄存器的四个组件来获得一个浮点数.这是我现在这样做的方式:
float a[4];
_mm_storeu_ps(a, foo128);
float x = a[0] + a[1] + a[2] + a[3];
Run Code Online (Sandbox Code Playgroud)
是否有直接实现此目的的SSE指令?
我目前正在开发一个开源的3D应用程序框架的C++(用C++ 11).我自己的数学库的设计类似于XNA数学库,同时考虑了SIMD.但目前它并不是很快,而且它在内存中存在问题,但在另一个问题上更多.
几天前我问自己为什么要编写自己的SSE代码.编译器还可以在启用优化时生成高优化代码.我也可以使用GCC的" 向量扩展 " .但这一切都不是真正的便携式.
我知道当我使用自己的SSE代码时,我有更多的控制权,但通常这种控制是不公平的.
SSE的一个大问题是使用动态内存,这在内存池和面向数据的设计的帮助下,尽可能地受到限制.
现在问我的问题:
我应该使用裸SSE吗?也许是封装的.
__m128 v1 = _mm_set_ps(0.5f, 2, 4, 0.25f);
__m128 v2 = _mm_set_ps(2, 0.5f, 0.25f, 4);
__m128 res = _mm_mul_ps(v1, v2);
Run Code Online (Sandbox Code Playgroud)或者编译器应该做脏工作吗?
float v1 = {0.5f, 2, 4, 0.25f};
float v2 = {2, 0.5f, 0.25f, 4};
float res[4];
res[0] = v1[0]*v2[0];
res[1] = v1[1]*v2[1];
res[2] = v1[2]*v2[2];
res[3] = v1[3]*v2[3];
Run Code Online (Sandbox Code Playgroud)或者我应该使用SIMD和其他代码吗?就像具有SIMD操作的动态容器类一样,需要额外的load和store指令.
Pear3D::Vector4f* v1 = new Pear3D::Vector4f(0.5f, …Run Code Online (Sandbox Code Playgroud)我想将两个__m128值组合成一个__m256.
像这样的东西:
__m128 a = _mm_set_ps(1, 2, 3, 4);
__m128 b = _mm_set_ps(5, 6, 7, 8);
Run Code Online (Sandbox Code Playgroud)
类似于:
__m256 c = { 1, 2, 3, 4, 5, 6, 7, 8 };
Run Code Online (Sandbox Code Playgroud)
我可以使用任何内在函数来做到这一点吗?
我正在阅读英特尔的内在指南,同时实现SIMD支持.我有一些困惑,我的问题如下.
__m128 _mm_cmpeq_ps (__m128 a, __m128 b)文档说它用于比较打包的单精度浮点数."打包"是什么意思?在使用它们之前,我是否需要以某种方式打包我的浮动值?
对于双精度,有内在函数,比如_mm_cmpeq_sd"比较"双精度浮点元素.低和高双精度elemtns是什么意思?我可以使用它们来比较C++ double类型元素的向量吗?或者在比较之前我是否需要以某种方式处理它们?