我试图在x64计算机上编译这个程序:
#include <cstring>
int main(int argc, char* argv[])
{
return ::std::strcmp(argv[0],
"really really really really really really really really really"
"really really really really really really really really really"
"really really really really really really really really really"
"really really really really really really really really really"
"really really really really really really really really really"
"really really really really really really really really really"
"really really really really really really really really really"
"really really really really really really …
Run Code Online (Sandbox Code Playgroud) 我今天正在阅读研究人员发现NVidia的Phys-X库使用x87 FP与SSE2.显然,对于速度超过精度的并行数据集来说,这将是次优的.然而,文章作者继续引用:
英特尔在2000年末引入P4后开始不鼓励使用x87.AMD自2003年K8以来已弃用x87,因为x86-64定义为SSE2支持; VIA的C7自2005年以来一直支持SSE2.在64位版本的Windows中,x87不适用于用户模式,完全禁止在内核模式下使用.自2005年以来,业内所有人都推荐SSE超过x87,除非软件必须在嵌入式Pentium或486上运行,否则没有理由使用x87.
我想知道这件事.我知道x87内部使用80位扩展双精度值来计算值,而SSE2则不然.这对任何人都没关系吗?这对我来说似乎很惊讶.我知道当我对平面中的点,线和多边形进行计算时,在进行减法时,值可能出乎意料地错误,并且由于缺乏精度,区域可能会折叠并且线条会相互别名.我想,使用80位值与64位值可能会有所帮助.
这是不正确的?如果没有,如果x87被淘汰,我们可以用什么来执行扩展的双FP操作?
我已经在我的C++项目中添加了x64配置来编译我的应用程序的64位版本.一切看起来都很好,但编译器发出以下警告:
`cl : Command line warning D9002 : ignoring unknown option '/arch:SSE2'`
Run Code Online (Sandbox Code Playgroud)
SSE2优化真的不适用于64位项目吗?
我目前编码的一些C99标准库字符串函数高度优化的版本,例如strlen()
,memset()
等等,采用x86-64的组件,SSE-2指令.
到目前为止,我已经在性能方面取得了很好的成绩,但是当我尝试优化更多时,我有时会遇到奇怪的行为.
例如,添加或甚至删除一些简单的指令,或者只是重新组织一些用于跳转的本地标签会完全降低整体性能.在代码方面绝对没有理由.
所以我的猜测是代码对齐存在一些问题,和/或有错误预测的分支.
我知道,即使使用相同的架构(x86-64),不同的CPU也有不同的分支预测算法.
但是,在开发x86-64的高性能时,是否存在一些关于代码对齐和分支预测的一般建议?
特别是关于对齐,我应该确保跳转指令使用的所有标签都在DWORD上对齐吗?
_func:
; ... Some code ...
test rax, rax
jz .label
; ... Some code ...
ret
.label:
; ... Some code ...
ret
Run Code Online (Sandbox Code Playgroud)
在前面的代码中,我之前应该使用align指令.label:
,例如:
align 4
.label:
Run Code Online (Sandbox Code Playgroud)
如果是这样,使用SSE-2时是否足以对齐DWORD?
关于分支预测,是否有一种"优先"的方式来组织跳转指令使用的标签,以帮助CPU,或者今天的CPU是否足够聪明,可以通过计算分支的计数来确定在运行时?
编辑
好的,这是一个具体的例子 - 这是strlen()
SSE-2 的开始:
_strlen64_sse2:
mov rsi, rdi
and rdi, -16
pxor xmm0, xmm0
pcmpeqb xmm0, [ rdi ]
pmovmskb rdx, xmm0
; ...
Run Code Online (Sandbox Code Playgroud)
使用1000个字符串运行10'000'000次约为0.48秒,这很好.
但它不会检查NULL字符串输入.显然,我会添加一个简单的检查:
_strlen64_sse2:
test rdi, rdi
jz .null
; ... …
Run Code Online (Sandbox Code Playgroud) 当使用SSE2指令,如PADDD
(即_mm_add_epi32
内在),有没有办法来检查任何操作是否溢出?
我想也许MXCSR控制寄存器上的标志可能在溢出后设置,但我没有看到这种情况发生.例如,_mm_getcsr()
在以下两种情况下打印相同的值(8064):
#include <iostream>
#include <emmintrin.h>
using namespace std;
void main()
{
__m128i a = _mm_set_epi32(1, 0, 0, 0);
__m128i b = _mm_add_epi32(a, a);
cout << "MXCSR: " << _mm_getcsr() << endl;
cout << "Result: " << b.m128i_i32[3] << endl;
__m128i c = _mm_set_epi32((1<<31)-1, 3, 2, 1);
__m128i d = _mm_add_epi32(c, c);
cout << "MXCSR: " << _mm_getcsr() << endl;
cout << "Result: " << d.m128i_i32[3] << endl;
}
Run Code Online (Sandbox Code Playgroud)
有没有其他方法来检查SSE2的溢出?
我想使用Valgrind 3.7.0在我的Java本机代码中查找内存泄漏.我正在使用jdk1.6.0._29.
为此,我必须设置--trace-children = yes标志.设置该标志,我不再可以在任何java应用程序上运行valgrind,甚至可以执行以下命令:
valgrind --trace-children=yes --smc-check=all java -version
Run Code Online (Sandbox Code Playgroud)
将收到错误消息:
Error occurred during initialization of VM
Unknown x64 processor: SSE2 not supported
Run Code Online (Sandbox Code Playgroud)
我已经看过这个链接:https://bugs.kde.org/show_bug.cgi?id = 249943,但它没用.
没有Valgrind或没有--trace-children标志运行程序就可以了.
有谁知道我能做什么?
如何将4个32位整数乘以另外4个整数?我没有找到任何可以做到的指令.
不同类型的逻辑SSE内在函数之间有什么区别吗?例如,如果我们采用OR运算,有三个内在函数:_mm_or_ps,_mm_or_pd和_mm_or_si128所有这些都做同样的事情:计算其操作数的按位 OR.我的问题:
使用一个或另一个内在(使用适当的类型转换)之间是否有任何区别.在某些特定情况下,是否会有更长的执行等隐藏成本?
这些内在函数映射到三个不同的x86指令(por,orps,orpd).有没有人有任何想法为什么英特尔浪费宝贵的操作码空间的几个指令做同样的事情?
其实我有两个问题:
我正在使用GCC版本:
gcc (GCC) 4.5.1
Run Code Online (Sandbox Code Playgroud)
当我尝试编译代码时,它给了我这个错误:
$ gcc -O3 -msse2 -fno-strict-aliasing -DHAVE_SSE2=1 -DMEXP=19937 -o test-sse2-M19937 test.c
cc1: error: unrecognized command line option "-msse2"
Run Code Online (Sandbox Code Playgroud)
并cpuinfo
显示:
processor : 0
vendor : GenuineIntel
arch : IA-64
family : 32
model : 1
model name : Dual-Core Intel(R) Itanium(R) Processor 9140M
revision : 1
archrev : 0
features : branchlong, 16-byte atomic ops
cpu number : 0
cpu regs : 4
cpu MHz : 1669.000503
itc MHz : 416.875000
BogoMIPS …
Run Code Online (Sandbox Code Playgroud) xmm
在32位模式下,在SSE2寄存器中加载64位整数值的最佳/最快方法是什么?
在64位模式下,cvtsi2sd
可以使用,但在32位模式下,它仅支持32位整数.
到目前为止,我还没有发现更多:
fild
,fstp
以堆叠然后movsd
到xmm
寄存器第一个解决方案很慢,第二个解决方案可能会引入精度损失(编辑:无论如何它都很慢,因为低32位必须转换为无符号...)
有更好的方法吗?