SSE半数负载(_mm_loadh_pi / _mm_loadl_pi)发出警告
我从英特尔网站上借了矩阵反转算法: http://download..intel.com/design.intel.com/design/pentimin/pentiumiii/pentiumiii/sml/sml/24504301.pdf 它使用_mm_loadh_pi和_mm_loadl_pi加载4x4矩阵系数,并同时进行部分改组.我的应用程序的性能提高非常重要,如果我使用_mm_load_ps进行矩阵的经典负载/随机降低,则稍慢. 但是,这种负载方法发出了汇编警告:" TMP1在此功能中未经初始化使用" __m128 tmp1; tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src)), (__m64*)(src+ 4)); 在某种程度上有意义,因为TMP1是_mm_loadl_pi的输入参数,并且会影响结果. 但是,查看代码所做的详细信息表明TMP1不需要初始化.初始化略微放慢了代码(可以测量).
0 2023-11-27
编程技术问答社区
XMM寄存器值的含义在Visual Studio调试器的寄存器窗口中显示
我发现在Visual Studio的寄存器窗口中很难解释XMM寄存器的值. Windows显示以下内容: XMM0 = 00000000000000004018000000000000 XMM1 = 00000000000000004020000000000000 XMM2 = 00000000000000000000000000000000 XMM3 = 00000000000000000000000000000000 XMM4 = 00000000000000000000000000000000 XMM5 = 00000000000000000000000000000000 XMM6 = 00000000000000000000000000000000 XMM7 = 00000000000000000000000000000000 XMM00 = +0.00000E+000 XMM01 = +2.37500E+000 XMM02 = +0.0000
2 2023-11-25
编程技术问答社区
VC++的SSE代码生成--这是一个编译器错误吗?
VC ++中非常特殊的代码序列生成以下指令(对于Win32): unpcklpd xmm0,xmmword ptr [ebp-40h] 2个问题: (1)据我了解英特尔手册,UNPCKLPD接受第二个参数为128个与众不同的内存地址.如果地址是相对于堆栈框架对齐的,则不能强制强制.这真的是编译器错误吗? (2)只有在从辩论者运行时,才能在执行此指令的执行时抛出异常,甚至并非总是如此.即使连接到过程并执行此代码也不会投掷.这怎么可能是? 抛出的特定例外是在0xffffffff处访问违规行为,但Afaik只是未对准的代码. [编辑:] 这是一些证明不良代码生成的来源 - 但通常不会导致崩溃. (这主要是我想知道的) [编辑2:] 现在,代码示例重现了实际崩溃.这也崩溃了调试器 - 我怀疑差异是因为调试器在不同的典型基础地址启动程序. // mock.cpp #include struct mock
0 2023-11-25
编程技术问答社区
Visual Studio 2017。_mm_load_ps经常被编译为movups
我正在查看我的代码生成的组件(使用Visual Studio 2017),并注意到_mm_load_ps经常(总是?)汇编为移动. 我正在使用_mm_load_ps上的数据是这样定义的: struct alignas(16) Vector { float v[4]; } // often embedded in other structs like this struct AABB { Vector min; Vector max; bool intersection(/* parameters */) const; } 现在,当我使用此构造时,将会发生以下内容: // this code __mm128 bb_min = _mm_load_ps(min.v); // generates this movups xmm4, XMMWORD PTR [r8] 我期望由于载体(16)而引起动作.在这种情况下,我还需要其他内容来说
0 2023-11-24
编程技术问答社区
在Visual Studio 2015中检测要与C++宏一起使用的SIMD指令集
所以,这是我要实现的目标.在我的C ++项目中,必须与Microsoft Visual Studio 2015或更高版本一起编译,我需要让一些代码具有不同的版本,具体取决于用户CPU中可用的最新SIMD仪器集,其中包括: SSE,SSE2,SSE3,SSSE3,SSE4.1,SSE4.2,AVX,AVX2和AVX2和AVX512. 由于此时我要寻找的是编译时间CPU派遣,所以我的第一个猜测是可以使用编译器宏很容易地完成它.但是,令我惊讶的是,很难找到有关如何在VS2015中使用宏来派遣此类CPU的信息. 例如,前一个问题" 检测可用性Visual Studio中设置的SSE2指令"具有有关如何检测X86代码的SSE和SSE2的信息,但对于X64代码而言,没有信息.虽然,他们引用了此Microsoft的文档: http://msdn.microsoft .com/en-us/library/b0084kay.aspx 在那里,我们只有有关如何检测SSE,SSE2,AVX和
0 2023-11-24
编程技术问答社区
比起加0.5f和用截断法转换,是否有更直接的方法将浮点数转换为int数?
从浮点转到int的转换,舍入的转换通常在与浮点数据一起使用的C ++代码中经常发生.例如,一种用途是生成转换表. 考虑这个代码片段: // Convert a positive float value and round to the nearest integer int RoundedIntValue = (int) (FloatValue + 0.5f); c/c ++语言将(int)施放为截断,因此必须添加0.5F以确保四舍五入到最近的正整数(当输入为正时).对于上述,VS2015的编译器生成以下代码: movss xmm9, DWORD PTR __real@3f000000 // 0.5f addss xmm0, xmm9 cvttss2si eax, xmm0 上面有效,但可能更有效... Intel的设计师显然认为,用单个指令可以完成需要的事情,这是一个重要的问题:转换为最近的整数值:cvtsss2si(注意,在助记符中只有一个
0 2023-11-24
编程技术问答社区
为什么在这个例子中,预取速度没有更大?
在此 但是,为什么预购在这里只有8%的帮助?如果我们告诉处理器正是我们要加载的内容,并且我们提前告诉了它足够远(他做了160个周期),为什么缓存不满足每个访问权限?他没有提及他的节点大小,因此在只需要一些数据时获取完整的线可能会有一些浪费? 我试图将_mm_prefetch与树一起使用,我认为没有明显的速度.我正在做这样的事情: _mm_prefetch((const char *)pNode->m_pLeft, _MM_HINT_T0); // do some work traverse(pNode->m_pLeft); traverse(pNode->m_pRight) 现在只能帮助一侧遍历遍历,但我只能看到性能的变化.我确实在项目设置中添加/拱门:SSE.我正在使用i74770.一些人还谈论仅通过预购获得1%的速度.为什么预摘要不起作用的奇迹,以便随机访问主内存中的数据? 解决方案 预摘要不能增加主内存的吞吐量,它只能帮助您更接近使用它. 如果您的代码
0 2023-11-23
编程技术问答社区
清除__m128i的上部字节
如何清除__m128i>>? 的16 - i上字节 我已经尝试过.它有效,但我想知道是否有更好的(较短,更快)的方式: int i = ... // 0 14) ? -1 : 0, (i > 13) ? -1 : 0, (i > 12) ? -1 : 0, (i > 11) ? -1 : 0, (i > 10) ? -1 : 0, (i > 9) ? -1 : 0, (i > 8) ? -1 : 0, (i > 7) ? -1 : 0, (i > 6) ? -1 : 0, (i > 5) ? -1 : 0, (i > 4) ? -1 : 0, (i > 3) ? -1 : 0, (i > 2) ? -1 : 0,
0 2023-11-23
编程技术问答社区
如何在visual studio 2010中添加SIMD相关的编译器标志
我找到了这个标志列表: 我想尝试将其中的一些添加到我的项目中.我似乎找不到在Visual Studio 2010平台上进行操作的方法:( 有人知道该怎么做吗? 谢谢!!! 解决方案 /Arch ">/acrach 在Visual Studio中的标志允许您指定目标处理器体系结构,并包括对SSE2的支持.此 Visual Studio还支持 sse2的表达用法说明通过
0 2023-11-23
编程技术问答社区
使用AVX CPU指令。在没有"/arch:AVX "的情况下性能不佳
我的C ++代码使用SSE,现在我想将其改进以在可用时支持AVX.因此,我检测到何时可用,并调用使用AVX命令的函数.我使用win7 sp1 + vs2010 sp1和带有avx的CPU. 要使用AVX,必须包括以下内容: #include "immintrin.h" 然后您可以使用intinsics avx函数,例如_mm256_mul_ps,_mm256_add_ps. 问题是默认情况下,VS2010产生的代码非常缓慢,并显示警告: 警告C4752:找到Intel(R)高级向量扩展;考虑 使用/拱门:avx 似乎VS2010实际上没有使用AVX指令,而是模仿它们.我在编译器选项中添加了/arch:AVX,并获得了良好的结果.但是此选项告诉编译器在可能的情况下在任何地方使用AVX命令.因此,我的代码可能会在不支持AVX的CPU上崩溃! 因此,问题是如何使VS2010编译器生成AVX代码,但仅当我直接指定AVX Intrinsics时.对于SSE起作用,
0 2023-11-23
编程技术问答社区
有什么方法可以强迫visual studio从SSE内在因素中生成对齐的指令吗?
_mm_load_ps()sse intinsic是由于并非所有编译器都相同,因此隐藏了错误.能够能够打开实际的对齐操作,即使以前的性能似乎不再存在. 换句话说,编写代码: __m128 p1 = _mm_load_ps(data); 当前生产: movups xmm0,xmmword ptr [eax] 预期结果: movaps xmm0,xmmword ptr [eax] (我是 shere Microsoft问 Microsoft在此处问 解决方案 MSVC和ICC仅使用指令,这些说明在未启用AVX的情况下将负载折叠到内存源操作数时进行对齐检查,例如addps xmm0, [rax].与AVX不同,SSE内存源操作数需要对齐.但是您无法可靠地控制这种情况,并且在调试中通常不会构建它. 正如神秘主义者在 如果您的代码与clang-cl兼容,请使用Visual Studio代替MSVC.这是Clang的修改版本,试图更
0 2023-11-20
编程技术问答社区
奇怪的uint32_t到浮动数组的转换
我有以下代码段: #include #include static const size_t ARR_SIZE = 129; int main() { uint32_t value = 2570980487; uint32_t arr[ARR_SIZE]; for (int x = 0; x (arr[x]); } printf("%s\n", arr_dst[ARR_SIZE - 1] == arr_dst[ARR_SIZE - 2] ? "OK" : "WTF??!!"); printf("magic = %0.10f\n", a
2 2023-11-20
编程技术问答社区
acos(double)在x64和x32 Visual Studio上给出不同的结果。
acos(double)在x64和x32 ​​Visual Studio上给出了不同的结果. printf("%.30g\n", double(acosl(0.49990774364240564))); printf("%.30g\n", acos(0.49990774364240564)); 在x64上:1.0473040763868076 在x32上:1.0473040763868078 在linux4.4 x32和x64上启用了SSE:1.0473040763868078 有没有办法使VSX64 acos()给我1.0473040763868078结果? 解决方案 tl:dr:这是正常的,您无法合理地更改它. 32位库可以在X87寄存器中使用80位fp值作为其临时性,避免在每个操作后避免到64位double. (除非有一个整个单独的库,否则编译您自己的代码使用SSE不会更改库中的内容,甚至不会更改将数据传递到库的呼叫约定.但是,由于32位通过d
2 2023-11-20
编程技术问答社区
检测Visual Studio中SSE/SSE2指令集的可用性
如何通过Visual Studio编译器启用SSE/SSE2? 是否启用了SSE/SSE2? 我尝试了#ifdef __SSE__,但它不起作用. 解决方案 来自 _M_IX86_FP 扩展为一个值,该值指示使用了哪种/Arch 编译器选项: 0如果使用/Arch:Ia32 . 1如果使用/Arch:SSE . 2如果使用/Arch:SSE2 .如果未指定/Arch ,则此值是默认值. 我看不到任何提及_SSE_. 其他解决方案 _M_IX86_FP上的一些其他信息. _M_IX86_FP仅针对32位代码定义. 64位X86代码至少具有SSE2.您可以使用_M_AMD64或_M_X64确定代码是64位. #ifdef __AVX2__ //AVX2 #elif defined ( __AVX__ ) //AVX #elif (defined(_M_AMD64) || defined(_M_X64)) //SSE2 x64 #el
6 2023-11-20
编程技术问答社区
适用于AVX和SSE的visual studio的cpu dispatcher
我与两台计算机一起工作.一个没有AVX支持,一个没有AVX.让我的代码在运行时找到我的CPU支持的指令集并选择适当的代码路径将很方便. 我已经遵循Agner Fog的建议来制作CPU调度员( http:///www.agner.org/optimize/#vectorClass ).但是,在我的手机上,AVX汇编并与Visual Studio链接使用AVX启用代码会导致我运行时代码崩溃. 我的意思是,例如,我有两个源文件,其中一个带有SSE2指令集,其中有一些SSE2指令定义,另一个使用AVX指令集定义了,并带有一些AVX指令.在我的主要功能中,如果我仅引用SSE2功能,则代码仍然通过启用AVX和AVX指令的任何源代码而崩溃.我如何解决此问题的任何线索? 编辑: 好吧,我认为我隔离了这个问题.我正在使用Agner Fog的矢量类,并且将三个源文件定义为: //file sse2.cpp - compiled with /arch:SSE2 #include "vecto
0 2023-11-20
编程技术问答社区
SSE2的双倍乘法比标准乘法更慢
我想知道为什么使用SSE2指令的以下代码比标准C ++实现更慢. 这是代码: m_win = (double*)_aligned_malloc(size*sizeof(double), 16); __m128d* pData = (__m128d*)input().data; __m128d* pWin = (__m128d*)m_win; __m128d* pOut = (__m128d*)m_output.data; __m128d tmp; int i=0; for(; i
2 2023-11-20
编程技术问答社区
在x86-64中实现rint()。
MSVC 2012没有RINT()函数.对于32位,我正在使用以下内容: double rint(double x) { __asm { fld x frndint } } 这在x64中不起作用.有_mm_round_sd(),但这需要SSE4.什么是一种有效的无分支的无分支方式? 解决方案 RINT 64位模式 #include static inline double rint (double const x) { return (double)_mm_cvtsd_si32(_mm_load_sd(&x)); } 请参阅Agner Fog的优化C ++手册 for Lrint 32位模式 // Example 14.19 static inline int lrint (double const x) { // Round to nearest integer
0 2023-11-20
编程技术问答社区
有效地建立面积总和表
我正在尝试构建一个总区域表,以供以后在自适应阈值例程中使用.由于此代码将在临时软件中使用,因此我试图从中挤出尽可能多的周期. 对于性能,该表是每个像素的无符号整数. 当我附上轮廓仪时,我表明我最大的性能瓶颈在执行X-Pass时会发生. 计算的简单数学表达式是: sat_[y * width + x] = sat_[y * width + x - 1] + buff_[y * width + x] where the running sum resets at every new y position. 在这种情况下,sat_是代表SAT的无符号整数的1-D指针,buff_是8位无符号单色缓冲区. 我的实现如下: uint *pSat = sat_; char *pBuff = buff_; for (size_t y = 0; y
0 2023-11-20
编程技术问答社区
_MM_TRANSPOSE4_PS在GCC中引起编译器错误?
我是第一次在GCC中而不是MSVC编译我的数学库,然后遇到所有小错误,我击中了一个简单的错误: Line 284: error: lvalue required as left operand of assignment 第284行是什么?这个: _MM_TRANSPOSE4_PS(r, u, t, _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f)); (r,u和t都是__m128的所有实例) 那些熟悉xmmintrin.h /* Transpose the 4x4 matrix composed of row[0-3]. */ #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ do { \ __v4sf __r0 = (row0), __r1 = (row1), __r2 = (row
0 2023-11-20
编程技术问答社区