jjzjj

c++ - 使用 XMM0 寄存器和内存提取(C++ 代码)比仅使用 XMM 寄存器的 ASM 快两倍 - 为什么?

我正在尝试实现一些内联汇编程序(在VisualStudio2012C++代码中)以利用SSE。我想将7个数字相加1e9次,所以我将它们从RAM放置到xmm0到CPU的xmm6寄存器。当我使用以下代码在visualstudio2012中使用内联汇编时:C++代码:for(inti=0;i我的ASM代码:intcount=1000000000;doubleresVal=0.0;//placingvaluestoregister__asm{movsdxmm0,val1;placingvar1inxmm0registermovsdxmm1,val2movsdxmm2,val3movsdxmm3

c++ - 朴素矩阵乘法的优化(ICC vs GCC)

下面的代码使用一种非常直接的方法来计算矩阵乘积a*b并将结果存储在c中。该代码是在GCC4.4.6(使用-mtune=native)和英特尔编译器13.0.1上使用-O3编译的,GCC的速度明显更差(超过所用样本数据的两倍)。我很好奇造成这些差异的原因,但不幸的是,我对汇编输出不够熟悉,无法理解这里发生了什么。乍一看,似乎ICC在矢量化计算方面做得更好,但我无法破译更多。(这主要用于学习目的,因为我无法在生产中使用它!)void__attribute__((noinline))mm(//Line3intn,double*__restrict__c,double*__restrict__

c++ - 如何将两组 4 条短裤加载到 XMM 寄存器中?

我刚刚开始使用VisualC++2012使用SSE内部函数,我需要一些指导(没有双关语意)。我有两个数组,每个数组包含4个signedshort(因此每个数组都是64位的,总共128个)。我想将一个加载到XMM寄存器的高位,另一个加载到低位。我可以使用SSE内在函数有效地完成这项工作吗?如果是,怎么办? 最佳答案 SSE2:shortA[]={0,1,2,3};shortB[]={4,5,6,7};__m128ia,b,v;a=_mm_loadl_epi64((const__m128i*)A);b=_mm_loadl_epi64((

c++ - 静态/静态本地 SSE/AVX 变量是否阻塞了 xmm/ymm 寄存器?

使用SSE内在函数时,通常需要零vector。避免在调用函数时(每次有效地调用一些异或vector指令)在函数内创建零变量的一种方法是使用静态局部变量,如staticinline__m128inegate(__m128ia){static__m128izero=__mm_setzero_si128();return_mm_sub_epi16(zero,a);}似乎变量只在第一次调用函数时才被初始化。(我通过调用一个真正的函数而不是_mm_setzero_si128()内在函数来检查这一点。顺便说一下,它似乎只在C++中是可能的,而不是在C中。)(1)但是,一旦初始化发生:这是否会为程序

c++ - 为什么这个 C++ 成员函数没有被编译器用 -O3 优化?

下面声明的C++vector类中的norm成员函数被标记为const并且(据我所知)没有包含任何副作用。templatestructvector{doublev[N];doublenorm()const{doubleret=0;for(inti=0;i&x){returnx.norm()+x.norm();}如果我在vector的const实例化上多次调用norm(参见上面的test函数)gcc编译器(版本5.4)和优化打开(即-O3)然后编译器内联norm,但仍然计算norm的结果多次,即使结果不应该改变。为什么编译器不优化对norm的第二次调用而只计算一次这个结果?Thisansw

c++ - 为什么我的程序这么慢?

有人决定做一个快速测试,看看native客户端在速度方面与javascript相比如何。他们通过运行10000000sqrt计算并测量所花费的时间来做到这一点。使用javascript的结果:0.096秒,使用NaCl的结果:4.241秒......这怎么可能?速度不是首先使用NaCl的原因之一吗?还是我缺少一些编译器标志或其他东西?这是运行的代码:clock_tt=clock();floatresult=0;for(inti=0;iPS:这个问题是nativeclientmailinglist中出现的内容的编辑版本 最佳答案 注意

c++ - 检查 XMM 寄存器是否全为零

有没有办法检查__m128i变量中的所有位/字节/字等是否为0?在我的应用程序中,我必须检查__m128i变量中的所有整数是否都为零。我是否必须提取它们并分别进行比较?编辑:我现在做的是:intnext=0;do{//somecodenext=idata.m128i_i32[0]+idata.m128i_i32[1]+idata.m128i_i32[2]+idata.m128i_i32[3];}while(next>0);我需要的是检查idata是否全为零,而不必访问每个单独的元素,如果是则退出循环...根据Harold的评论,这是解决方案:__m128iidata=_mm_setr_

c++ - 为什么gcc/clang要用两个128bit的xmm寄存器来传递一个值?

所以我偶然发现了一些我想了解的东西,因为它让我头疼。我有以下代码:#include#includetypedefunion{struct{floatx,y,z,w;}v;__m128m;}vec;vec__attribute__((noinline))square(veca){vecx={.m=_mm_mul_ps(a.m,a.m)};returnx;}intmain(intargc,char*argv[]){floatf=4.9;veca=(vec){f,f,f,f};vecres=square(a);//?printf("%f%f%f%f\n",res.v.x,res.v.y,re

windows - 为什么 Windows x64 调用约定不使用 XMM 寄存器来传递超过 4 个整数参数?

(微软)x64callingconvention状态:TheargumentsarepassedinregistersRCX,RDX,R8,andR9.Iftheargumentsarefloat/double,theyarepassedinXMM0L,XMM1L,XMM2L,andXMM3L.这很好,但为什么只是float/加倍?为什么整数(可能还有指针)不也通过XMM寄存器传递?似乎有点浪费可用空间,不是吗? 最佳答案 因为大多数对非FP值(即整数和地址)的操作都设计为使用通用寄存器。有整数SSE运算,但它们只是算术运算。因此,

windows - 为什么 Windows 64 选择要求保存/恢复 xmm6 和 xmm7?

为什么Windows64选择要求保存/恢复xmm6和xmm7?在Windows32中,您可以编写破坏xmm0...xmm7的汇编例程。但是如果你采用相同的汇编代码并在Windows64中运行它,它通常会导致应用程序错误,因为VS2007在xmm6和xmm7中存储double值。在我看来,既然X64有16个xmm寄存器xmm0...xmm15(而X32只有8个xmm寄存器),那么微软本可以选择允许用户破坏xmm0..xmm7(以便他们可以重用程序集来自Win32的例程而无需考虑)但要求用户保存/恢复xmm8...xmm15。那么,为了满足我自己的好奇心,为什么Windows64选择要求保