POPPUR爱换

标题: 那位编程举个例子, 把sse的"威力"释放一下? [打印本页]

作者: 紫色    时间: 2007-9-29 19:46
标题: 那位编程举个例子, 把sse的"威力"释放一下?
图形图像我也相信sse肯定有用, 至于它的份额和重要程度, 已经讨论够多了,也没啥结果,这里不再继续,ok?

就选定数值计算编程,
为了公平起见,  结果请大家共同验证. 别人还没验证就不要自己先吹.
请提供:
1) 编译器,编译选项,
2) 同时提供使用sse与使用x87的程序运行时间,
3) 源代码.既然是数值计算,那么编程语言就是C或者fortran.
程序希望是现实点的别太极端太蠢到现实中根本不可能. 最好调用广泛使用的库如lapack等 ,或者调用intel的mkl生成随机向量做simulation之类的也行, 总之要比较符合现实.
来吧, "sse救命论"者们. 我很期待你们的程序能释放simd的威力!

[ 本帖最后由 紫色 于 2007-9-29 20:13 编辑 ]
作者: acqwer    时间: 2007-9-29 20:00
Spec2000,基本都是C和fortran的数值运算,发布的时候SSE刚出,代码显然是没有为SSE优化的。
除了SSE外规格完全相同的Athlon1600+和Athlon1.4G成绩:
http://www.spec.org/osg/cpu2000/ ... 20010519-00654.html
http://www.spec.org/osg/cpu2000/ ... 20011008-01021.html
Runtime在测试结果中都有。
作者: 紫色    时间: 2007-9-29 20:07
没有sse的成绩比较就等于没说. ifort好像是8.0才支持sse ,5.0应该是不支持sse的吧。

那些程序你去选择、编译并比较吧, 既然你也用linux, 如果需要,我给你提供ifort 10.0 for linux的lic(说实话我并不使用ifort)。
建议你干脆把那些程序全部编译一遍。事实也许会对你有利,也许会对我有利,都大白于阳光下好了~~

[ 本帖最后由 紫色 于 2007-9-29 20:15 编辑 ]
作者: acqwer    时间: 2007-9-29 20:13
Intel 01年出的编译器不支持SSE,你是在搞笑吧。
http://www.spec.org/cpu2000/results/res2001q2/cpu2000-20010507-00631.html
当然,你非要说P4的X87性能比同频的Athlon强我也没办法。

[ 本帖最后由 acqwer 于 2007-9-29 20:18 编辑 ]
作者: 紫色    时间: 2007-9-29 20:16
请教这里面,那个支持sse,是Intel C/C++ 5.0 build 1120 and Intel Fortran 5.0 build 1120 ?

Operating System:          Windows 2000 SP1
Compiler:         Compaq Visual Fortran 6.5A
Intel C/C++ 5.0 build 1120 and Intel Fortran 5.0 build 1120
Microsoft Visual Studio 6.0 (libraries)
MicroQuill Smartheap Library 5.0
File System:         FAT32
System State:         Default

[ 本帖最后由 紫色 于 2007-9-29 20:34 编辑 ]
作者: acqwer    时间: 2007-9-29 20:21
从P4的测试结果看,ifort5.0连SSE2都支持。
作者: rtyou    时间: 2007-9-29 20:22
SSE有什么威力?不知道,只知道现在的游戏必须有SSE支持的CPU,而不是3DNow!那个废物!w00t)
作者: Dr.BT    时间: 2007-9-29 20:27
:huh:
这个,好像amd有数据的
不过lz这样的bc看不懂,懒得拿出来了
作者: 紫色    时间: 2007-9-29 20:37
原帖由 Dr.BT 于 2007-9-29 20:27 发表
:huh:
这个,好像amd有数据的
不过lz这样的bc看不懂,懒得拿出来了


你还是省省吧,肉鸟
我都不想再把发给conXE的短信再向你发一遍了,这里所有人都知道你的类型。
不是我瞧不起你,你还比不上conXE呢,你连否定的能耐都没。

[ 本帖最后由 紫色 于 2007-9-29 21:01 编辑 ]
作者: 紫色    时间: 2007-9-29 21:10
原帖由 acqwer 于 2007-9-29 20:00 发表
Spec2000,基本都是C和fortran的数值运算,发布的时候SSE刚出,代码显然是没有为SSE优化的。
除了SSE外规格完全相同的Athlon1600+和Athlon1.4G成绩:
http://www.spec.org/osg/cpu2000/results/res2001q2/cpu ...


我看了cfp2000的结果。我觉得不可靠。首先,cvf ,ifort等编译器版本不一样。即使忽略版本,但对同一程序,甚至连编译器都不一样,这就不好比较了,因为不同编译器往往都有不小性能差。
171.swim:     f90 -Optimize:5 -fast
171.swim:     ifl -O3 -QxK -Qwp_ipo +FDO
等等。

你能否提供对这些程序的同一编译器不同选项的结果以供验证?
ifort/icc ,
pgi
gcc/gfortran ?

[ 本帖最后由 紫色 于 2007-9-29 21:16 编辑 ]
作者: boris_lee    时间: 2007-9-29 21:15
原帖由 紫色 于 2007-9-29 21:10 发表


我看了cfp2000的结果。我觉得不可靠。首先,cvf ,ifort等编译器版本不一样。即使忽略版本,但对同一程序,甚至连编译器都不一样,这就不好比较了,因为不同编译器往往都有不小性能差。
171.swim:     f90  ...

嗯,Spec不可靠,tom是枪手 ,拿Linus宣传kerneltrap ,但Linus怎么想无关紧要
其实只要两个字就够了.
I Believe.
作者: 紫色    时间: 2007-9-29 21:18
不要打岔,不要断章取义。我说的是相关数据用于作比较不可靠。
说到believe,你要拿出烧饼而不是画饼,才能让别人believe。
你觉得多弄些人凭空想象、彼此支持、彼此吹拍甚至还不存在的nehalem有多强,就能让别人都信服?人多了没用,100个零加起来还是零。

[ 本帖最后由 紫色 于 2007-9-29 21:29 编辑 ]
作者: itany    时间: 2007-9-29 21:28
原帖由 紫色 于 2007-9-29 21:18 发表
不要打岔,不要断章取义。我说的是相关数据用于作比较不可靠。
说到believe,你要拿出烧饼而不是画饼,才能让别人believe。
你觉得多弄些人凭空想象、彼此支持、彼此吹拍甚至还不存在的nehalem有多强,就能让 ...


别人有义务让您信服吗?
某些人在Nehalem出来之后也不会信服的
对于没有决策权的人士,是不是Believe=0,花时间证明这种显然的东西显然是在浪费生命

[ 本帖最后由 itany 于 2007-9-29 21:32 编辑 ]
作者: acqwer    时间: 2007-9-29 21:31
Spec官网摆在这,自己去翻。论X87性能,P3/P4远不如Athlon,它们是靠什么压倒同频的K7?

至于nehalem多强,只要最终的设计达到intel所宣传的,那么nehalem的FP_rate不会输给任何对手,在确认nehalem无法达到intel宣传之前,你没有任何理由阻止别人yy nehalem的性能,就像在K10和R600发布前,没人阻止Afan yy一样。

[ 本帖最后由 acqwer 于 2007-9-29 21:38 编辑 ]
作者: 晶晶守护神    时间: 2007-9-29 21:36
提示: 作者被禁止或删除 内容自动屏蔽
作者: akeyyeka    时间: 2007-9-29 21:40
spec源代码花钱就能买到,自己用sse开关编译一下不就晓得了。老等别人证明给你看。

BTW,我不相信地球是圆的,哪位证明给我看一下?
作者: potomac    时间: 2007-9-29 22:39
提示: 作者被禁止或删除 内容自动屏蔽
作者: Ricepig    时间: 2007-9-29 22:42
其实就一个矩阵乘法,有SSE会快不少.
SSE本身速度快是现实,但是目前貌似算法能适应SSE的不多,即很大部分问题不能用SIMD模式的算法搞定~~~
作者: Dr.BT    时间: 2007-9-29 22:46
原帖由 akeyyeka 于 2007-9-29 21:40 发表
spec源代码花钱就能买到,自己用sse开关编译一下不就晓得了。老等别人证明给你看。

BTW,我不相信地球是圆的,哪位证明给我看一下?

因为自己从来没东西可以证明的
只需要满嘴大炮就可以了
w00t)
所以,先下手为强
对付君子会有优势:huh:
对付邪恶的君子么w00t)

很简单的惯例,谁指证谁举证嘛
要想只让被指证的人举证也容易啊,自己开个bbs,然后虚拟机个人进来被自己这样欺负不就可以了:shifty:

[ 本帖最后由 Dr.BT 于 2007-9-29 22:48 编辑 ]
作者: acqwer    时间: 2007-9-29 22:46
原帖由 Ricepig 于 2007-9-29 22:42 发表
其实就一个矩阵乘法,有SSE会快不少.
SSE本身速度快是现实,但是目前貌似算法能适应SSE的不多,即很大部分问题不能用SIMD模式的算法搞定~~~


http://en.wikipedia.org/wiki/AMD64

The original AMD64 architecture adopted Intel's SSE and SSE2 as core instructions.SSE3 instructions were added in April 2005. SSE2 replaces the x87instruction set's IEEE 80-bit precision, with the choice of either IEEE32-bit or 64-bit floating-point mathematics. This providesfloating-point operations compatible with many other modern CPUs. TheSSE and SSE2 instructions have also been extended to support the eightnew XMM registers. SSE and SSE2 are available in 32-bit mode in modernx86 processors; however, if they're used in 32-bit programs, thoseprograms will only work on systems with processors that support them.This is not an issue in 64-bit programs, as all processors that supportAMD64 support SSE and SSE2, so using SSE and SSE2 instructions insteadof x87 instructions does not reduce the set of machines on which theprograms will run. Since SSE and SSE2 are generally faster than, andduplicate most of the features of, the traditional x87 instructions, MMX, and 3DNow!, the latter are redundant under AMD64.

[ 本帖最后由 acqwer 于 2007-9-29 22:48 编辑 ]
作者: Ricepig    时间: 2007-9-29 22:49
原帖由 acqwer 于 2007-9-29 22:46 发表


http://en.wikipedia.org/wiki/AMD64

The original AMD64 architecture adopted Intel's SSE and SSE2 as core instructions.SSE3 instructions were added in April 2005. SSE2 replaces the x87instru ...

1) "the latter"是多久
2) 虽然SSE可能和x87指令一样快,但是我说的"不是所有问题都可以用SIMD模式解决"也没啥不对吧,至少很多问题在CPU上跑,将远达不到峰值吞吐量
作者: Intelife    时间: 2007-9-29 22:50
举例子是可以的,但就怕你看不懂。
举例详解
下面的程序是一个矩阵相乘的函数。在三维图形空间变换中,要用到4乘4的浮点矩阵,
而矩阵相乘的运算是很常用的。下面的函数的参数都是4乘4的浮点矩阵。写成这种形式
是为了保持比较强的伸缩性。
void MatMul_cpp(float *dest, float *m1, float *m2)
{
    for(int i = 0; i < 4; i ++)
    {
        for(int j = 0; j < 4; j ++)
        {
            dest[i*4+j] =
                m1[i*4+0]*m2[0*4+j] +
                m1[i*4+1]*m2[1*4+j] +
                m1[i*4+2]*m2[2*4+j] +
                m1[i*4+3]*m2[3*4+j] ;
        }
    }
}
VC的优化能力是很强的,象上面这样的比较常规的算法,你很难做出比它快得多的代码
。不过使用SSE以后就不一样了。下面是一个汇编函数,使用SSE 指令进行计算。注意,这个函数只能运行于32位的环境中。“.xmm”指示编译器使用SSE指令集进行编译。
函数的C语言原型是这样的:
extern "C"
{
void __stdcall MatMul_xmm(float *dest, float *m1, float *m2);
}
对于一些不太常用汇编语言编程的朋友来说,下面的程序可能比较难于理解。我将对一些常识性的东西做一下简单介绍。
在C语言中,代码段都是以“_TEXT”作为段名的。“use32”告诉编译器将代码编译为32位。
有些人看到“_MatMul_xmm@12”这个函数名以后可能会产生疑问。其实这只是遵循了VC所采用的命名规范。在VC中,所有标志为“__stdcall” 调用的,采用“C”链接的函数都要加下划线作为前缀,并且加上“@N”作为后缀,其中,“N”为参数的字节数。注意,上面的函数是采用“C”链接的,如果是“C++”链接,命名规范就太复杂了。如果你使用的是C++ Builder,命名规范就十分简单了,照搬函数名就行了。不同的调用规范将采用不同的命名方法,即使对相同的调用规范,不同的编译器也不一定兼容。有一种调用格式是每一个C++编译器都支持并且兼容的,那就是“__cdecl”。
各种调用格式所采用的堆栈操作也不太一样。使用“__stdcall”时,参数从右向左依次入栈,参数的弹出需要函数自己来处理。这种做法和“__cdecl” 调用方式不太一样,“__cdecl”的参数弹出需要调用者来处理。现在很流行的一种调用格式是“__fastcall”,也就是寄存器调用。这种调用方式通过寄存器“EAX”,“ECX”,“EDX”传递参数,不过很可惜,这种调用也不是在各个编译器中兼容的。Inprise在C++ Builder中提供了一个关键字“__msfastcall” 用来和微软兼容,如果你采用这种调用规范就可以在多个编译器中正常调用了。不过还有一件事让人很受打击,VC没有对“__fastcall”提供很好的优化,使用这种调用反而会降低效率。并不是所有的寄存器都能够随意使用的,多数32位寄存器都要先保存的。你可以不必保存的32位寄存器只有三个----“EAX”,“ECX”,“EDX”,其它的就只好“PUSH”,“POP”了。另外,浮点堆栈寄存器是不必保存的;MMX 寄存器和浮点堆栈共享,也是不必保存的;XMM寄存器不必保存。
很多SSE指令都会加上“ps”或“ss”后缀。“ps”表示“Packed Single-FP”,即打包
的浮点数,带这种后缀的指令通常是一次性对四个数进行操作的。“ss” 表示“Scalar Single-FP”,带这种后缀的指令通常是对最低位的单精度数进行操作的。
下面这个汇编函数是一行一行计算的,咱们先用类似于C的语法简述一下第一行的计算过
程:
    xmm0 = m1[0],m1[0],m1[0],m1[0];
    xmm1 = m1[1],m1[1],m1[1],m1[1];
    xmm2 = m1[2],m1[2],m1[2],m1[2];
    xmm3 = m1[3],m1[3],m1[3],m1[3];
    xmm4 = m2[0],m2[1],m2[2],m2[3];
    xmm5 = m2[4],m2[5],m2[6],m2[7];
    xmm6 = m2[8],m2[9],m2[10],m2[11];
    xmm7 = m2[12],m2[13],m2[14],m2[15];
    xmm0 *= xmm4;
    xmm1 *= xmm5;
    xmm2 *= xmm6;
    xmm3 *= xmm7;
    xmm1 += xmm0;
    xmm2 += xmm1;
    xmm3 += xmm2;
    dst[0],dst[1],dst[2],dst[3] = xmm3;
上面的代码可读性还是比较好的,因为只进行了第一行的计算。实际运算中,为了增强并行度,为了减小指令的延迟,实际上是两行并行计算的。而且,运算过程并不是象算法描述那样写得那么有规律。
        .686p
        .xmm
        .model flat
_TEXT segment public use32 'CODE'
public _MatMul_xmm@12
_MatMul_xmm@12 proc
;;parameters
retaddress = 0
dst = retaddress+4
m1 = dst+4
m2 = m1+4
        mov          edx,     [esp+m1]
        mov          ecx,     [esp+m2]
        mov          eax,     [esp+dst]
        movss        xmm0,    [edx+16*0+4*0]   ;读入第一行的数据
        movaps       xmm4,    [ecx+16*0]
        movss        xmm1,    [edx+16*0+4*1]
        shufps       xmm0,    xmm0,    00h
        movaps       xmm5,    [ecx+16*1]
        movss        xmm2,    [edx+16*0+4*2]
        shufps       xmm1,    xmm1,    00h
        mulps        xmm0,    xmm4
        movaps       xmm6,    [ecx+16*2]
        mulps        xmm1,    xmm5
        movss        xmm3,    [edx+16*0+4*3]
        shufps       xmm2,    xmm2,    00h
        movaps       xmm7,    [ecx+16*3]
        shufps       xmm3,    xmm3,    00h
        mulps        xmm2,    xmm6
        addps        xmm1,    xmm0
        movss        xmm0,    [edx+16*1+4*0]   ;读入第二行的数据
        mulps        xmm3,    xmm7
        shufps       xmm0,    xmm0,    00h
        addps        xmm2,    xmm1
        movss        xmm1,    [edx+16*1+4*1]
        mulps        xmm0,    xmm4
        shufps       xmm1,    xmm1,    00h
        addps        xmm3,    xmm2
        movss        xmm2,    [edx+16*1+4*2]
        mulps        xmm1,    xmm5
        shufps       xmm2,    xmm2,    00h
        movaps       [eax+16*0],    xmm3
        movss        xmm3,    [edx+16*1+4*3]
        mulps        xmm2,    xmm6
        shufps       xmm3,    xmm3,    00h
        addps        xmm1,    xmm0
        movss        xmm0,    [edx+16*2+4*0]   ;读入第三行的数据
        mulps        xmm3,    xmm7
        shufps       xmm0,    xmm0,    00h
        addps        xmm2,    xmm1
        movss        xmm1,    [edx+16*2+4*1]
        mulps        xmm0,    xmm4
        shufps       xmm1,    xmm1,    00h
        addps        xmm3,    xmm2
        movss        xmm2,    [edx+16*2+4*2]
        mulps        xmm1,    xmm5
        shufps       xmm2,    xmm2,    00h
        movaps       [eax+16*1],    xmm3
        movss        xmm3,    [edx+16*2+4*3]
        mulps        xmm2,    xmm6
        shufps       xmm3,    xmm3,    00h
        addps        xmm1,    xmm0
        movss        xmm0,    [edx+16*3+4*0]   ;读入第四行的数据
        mulps        xmm3,    xmm7
        shufps       xmm0,    xmm0,    00h
        addps        xmm2,    xmm1
        movss        xmm1,    [edx+16*3+4*1]
        mulps        xmm0,    xmm4
        shufps       xmm1,    xmm1,    00h
        addps        xmm3,    xmm2
        movss        xmm2,    [edx+16*3+4*2]
        mulps        xmm1,    xmm5
        shufps       xmm2,    xmm2,    00h
        movaps       [eax+16*2],    xmm3
        movss        xmm3,    [edx+16*3+4*3]
        mulps        xmm2,    xmm6
        shufps       xmm3,    xmm3,    00h
        addps        xmm1,    xmm0
        mulps        xmm3,    xmm7
        addps        xmm2,    xmm1
        addps        xmm3,    xmm2
        movaps       [eax+16*3],    xmm3
        ret          12
_MatMul_xmm@12 endp
_TEXT ends
        end
作者: boris_lee    时间: 2007-9-29 22:50
原帖由 Ricepig 于 2007-9-29 22:49 发表

1) "the latter"是多久

the latter 是后者,不是多久
这是几光年前学过的了(_(
作者: Intelife    时间: 2007-9-29 22:51
上面的代码几乎没有加什么注释,只是在读入每行第一个数据时作了标记。因为,SSE的指令可读性还是比较好的,除了要加上一些后缀以外,它们和普通的整数运算指令很相似。
一些关键性的指令有必要解释一下:
movss和movaps:
movss是将一个单精度数传输到xmm寄存器的低32位,而movaps则是一次性向寄存器中写入四个单精度数。也许有些人会认为movaps效率更高一些,其实并不一定是这样。从处理器执行单元列表中,你可以查到这些指令的延迟。如果都是从寄存器中读取数据,两个指令的延迟是一样的。如果是从内存中读取数据,movss只有一个时钟周期的延迟,而movaps却有四个时钟周期的延迟。
上面的汇编代码混合使用了这两条指令。那么,应该在什么时候选择哪一条指令呢?这要看你对数据的需求了。如果你希望能够尽快地使用数据,就应当首选movss,因为它几乎能够让你立即使用数据。如果你并不急于使用某些数据,只是想先把它读入寄存器,那么毫无疑问movaps是你的最佳选择。 movaps使用端口2读取数据,如果在它执行完毕之前你不去使用它的数据,这条指令的实际延迟就只有一个时钟周期。考虑到处理器能够在5个端口并行执行微操作,那么这条指令的延迟可能还不到一个时钟周期。从上面的代码中,你可以看到,每一条movaps指令和它的相关指令之间都至少插入了四条指令,这样可以基本上避免延迟。
虽然movss指令只有一个时钟周期的延迟,但是这也并不意味着你可以把这条指令和它的相关指令写在一起,因为这有可能会影响处理器的并行度。虽然 Pentium III有着强大的乱序执行的能力,可是这毕竟是不太保险的,还是自己动手,丰衣足食吧。
SHUFPS
这是一条可以将操作数打乱顺序的指令。这一条指令有很多种用法,它根据常量参数的不同执行不同的功能。本文中只使用了一种用法:
    shufps      xmmreg,  xmmreg,  00h
这条指令的作用是把某个寄存器的最低位的单精度数传输到该寄存器的其它三个部分。

在某些时候,shufps和unpcklps(或unpckhps)可以执行相同的功能。这时,推荐使用
shufps,因为这条指令有两个时钟周期的延迟。unpcklps和unpckhps 都是有三个时钟周
期的延迟。
ADDPS和MULPS
这两条指令是很重要的计算指令,有必要弄清楚它们的执行情况。
addps有4个时钟周期的延迟,mulps有5个时钟周期的延迟,我们应该根据这些数据考虑
清楚,究竟在它们的相关代码中插入多少条指令。
这两条指令都是每两个时钟周期才允许执行一次,如果你把相同的两条这样的指令写在一起,第二条指令就有可能被延误一个时钟周期。应该插入一些其它指令来掩盖这段延迟。
mulps在端口0执行,addps在端口1执行,如果你的代码把乘法和加法指令写在一起,它们会被分配到不同的端口并行执行,这比只有一条流水线的FPU要高效的多。
优化思路:
下面将解释一下上面代码的优化思路。
打乱指令
在算法描述中,各条操作写得非常有规律,但是在真正编程的时候却不是这样。为了保证流水线的流畅运作,就要把相关的代码分离开来,尽量避免或减轻指令的延迟。这样就要打乱指令,在两条相关指令之间插入一些其它的指令,同时也要考虑指令之间是否存在资源的竞争。
并行算法
多个数据并行计算是解决指令延迟问题的有效方法。我们不能傻傻地等待一条指令的计算结果,而是要在等待的过程中进行其它数据的计算。在上面程序的算法中,每当寄存器有了空闲,就马上从内存中读入新的数据,尽量保证有两组数据在寄存器中并行计算。
内存访问
访问内存的指令不要过于密集,这一方面可以减轻对带宽的需求,另一方面也会提高解码的效率。访问内存的指令至少有两个微操作,这样的指令只能每个时钟周期解码一条,而Pentium III的解码极限可是每个时钟周期三条指令啊。为了提高处理器的并行度,
有必要在内存访问指令上下功夫。在我的代码中,内存访问指令的排布还是比较有规律的,差不多是每隔三条指令访问一次内存。当然,在计算第一行数据时,因为要读取一些初始化的数据,内存访问比后面的代码要频繁。
灵活性
矩阵的运算是一行一行进行的,每一行数据只被读取一次。这就意味着,我们可以把运算结果保存在任何一个矩阵里,即保存在m1或者m2中,因为这两个矩阵中的数据已经不会被再次读取了,也就不用担心破坏数据。这种灵活性可以是我们轻而易举地完成矩阵左乘或者右乘的代码。在Direct3D中,空间变换是按照如下方式进行计算的:
在进行多次变换时,只要在原有的矩阵上右乘一个变换矩阵就可以了。下面的代码就是
这样的一个例子:
MatMul_xmm(m1, m1, m2);
如果使用高级语言来实现恐怕就要麻烦一些,你要使用一些中间变量,程序如下所示:

void MatMul_Right_cpp(float *dest, float *m)
{
    float tmp[16];
    MatMul_cpp(tmp, dest, m)
    memcpy(dest, tmp, 16*4);
}

要理解SSE的威力,必需了解一些关于CPU结构方面的知识,特别是寄存器,流水线,并行化和乱序执行等方面的知识,很明显,楼主对此一无所知。所以根本不可能理解SSE能够给程序带来什么样的性能提高,更别说什么释放simd的威力了。
作者: Ricepig    时间: 2007-9-29 22:52
原帖由 boris_lee 于 2007-9-29 22:50 发表

the latter 是后者,不是多久
这是几光年前学过的了(_(

哦,圡了,嘿嘿
作者: Dr.BT    时间: 2007-9-29 22:54
:huh: 给bc看代码干什么,看得懂才怪
就看看广告宣传的文字就可以了:
不认识e文说一下哦
我可以义务用google翻译成中文w00t)
The 64-bit and 128-bit SIMD instructions—SSE, SSE2, SSE3, SSE4a instructions—should be used to encode floating-point and packed integer operations.
The SIMD instructions use a flat register file rather than the stack register file used by x87 floating-point instructions. This allows arbitrary sequences of operations to map more efficiently to the instruction set.
•AMD Family 10h processors with 128-bit multipliers and adders achieve better throughput using SSE, SSE2, SSE3, and SSE4a instructions. (Double precision throughput is 2× and single precision is 4× the throughput of x87.)
•SSE, SSE2, SSE3, and SSE4a instructions work well in both 32-bit and 64-bit threads.
In 64-bit mode, there are twice as many XMM registers available as in 32-bit mode, however, the number of x87 registers is the same in both 32-bit mode and 64-bit mode.
The SIMD instructions provide a theoretical single-precision peak throughput of four additions and four multiplications per clock cycle, whereas x87 instructions can only sustain one addition and one multiplication per clock cycle. The double-precision peak throughput of the SSE, SSE2, SSE3, and SSE4a instructions is two additions and two multiplications per clock cycle.


so,via fanboy,get out:lol:

[ 本帖最后由 Dr.BT 于 2007-9-29 22:58 编辑 ]
作者: Ricepig    时间: 2007-9-29 22:57
原帖由 Intelife 于 2007-9-29 22:51 发表
上面的代码几乎没有加什么注释,只是在读入每行第一个数据时作了标记。因为,SSE的指令可读性还是比较好的,除了要加上一些后缀以外,它们和普通的整数运算指令很相似。
一些关键性的指令有必要解释一下:
mo ...

把SSE和流水线与乱续执行扯到一起,不太对吧,莫非普通指令和超标量与乱序没关系?
说并行和SIMD还有点谱
作者: Ricepig    时间: 2007-9-29 22:59
我查了一下Intel优化手册,似乎SSE和X87的最大差距就在80位浮点运算了,不过这个手册时间有点早,现在的SSE能搞定80位浮点数不?
作者: 紫色    时间: 2007-9-29 23:03
原帖由 Intelife 于 2007-9-29 22:50 发表
举例子是可以的,但就怕你看不懂。
举例详解
下面的程序是一个矩阵相乘的函数。在三维图形空间变换中,要用到4乘4的浮点矩阵,
而矩阵相乘的运算是很常用的。下面的函数的参数都是4乘4的浮点矩阵。写成这种形 ...


欢迎。

中山大学bbs这篇我也是看过的。可以说为sse而定制的程序。

那就请给出运行时间和编译选项,让大家看看这种类型的程序结果吧。
作者: Dr.BT    时间: 2007-9-29 23:03
原帖由 Ricepig 于 2007-9-29 22:59 发表
我查了一下Intel优化手册,似乎SSE和X87的最大差距就在80位浮点运算了,不过这个手册时间有点早,现在的SSE能搞定80位浮点数不?

是128位和64位吧:huh:
80位sse2/3打x87不爽
80bit当128bit玩的)_)
作者: Ricepig    时间: 2007-9-29 23:05
原帖由 紫色 于 2007-9-29 23:03 发表


欢迎。

中山大学bbs这篇我也是看过的。可以说为sse而定制的程序。

那就请给出运行时间和编译选项,让大家看看这种类型的程序结果吧。


最直观的例子,还是看看去年年底Intel多核编程大赛吧,里面的优化手册里面有好多资料,SSE对那个程序的性能提高确实大
作者: 紫色    时间: 2007-9-29 23:07
原帖由 Dr.BT 于 2007-9-29 22:54 发表
:huh: 给bc看代码干什么,看得懂才怪
就看看广告宣传的文字就可以了:
不认识e文说一下哦
我可以义务用google翻译成中文w00t)
The 64-bit and 128-bit SIMD instructions—SSE, SSE2, SSE3, SSE4a instruc ...


拜托,别来这个了。conXE反复强调,地球人也早就知道了:x87需要压栈。

拿出点本领出来,给出运行时间对比,证明单指令多数据的威力。
作者: Ricepig    时间: 2007-9-29 23:08
原帖由 Dr.BT 于 2007-9-29 23:03 发表

是128位和64位吧:huh:
80位sse2/3打x87不爽
80bit当128bit玩的)_)

不是,当时手册上说SSE不能算80位浮点
另外,我觉得你可能有点理解错了SSE的128位的意思,这128位其实是2个64位浮点拼起来的吧,不能支持单一大于64位的浮点运算.不知道现在的SSE能不能支持大于64位浮点了
作者: Dr.BT    时间: 2007-9-29 23:11
原帖由 Ricepig 于 2007-9-29 23:08 发表

不是,当时手册上说SSE不能算80位浮点
另外,我觉得你可能有点理解错了SSE的128位的意思,这128位其实是2个64位浮点拼起来的吧,不能支持单一大于64位的浮点运算.不知道现在的SSE能不能支持大于64位浮点了

sse当然可以直接128bit
否则c2d怎么玩转的,k10怎么玩转的
sse的确需要从架构上去看的
现在两家公司最新的产品都根本不需要拆分了
以前是没办法,现在么:whistling:
早期说的不能处理80bit你理解错了吧
是80bit处理效率没有优势
相比64bit

最近k10那个文档里也有不少sse优化的代码例子,也可以看一下

[ 本帖最后由 Dr.BT 于 2007-9-29 23:18 编辑 ]
作者: 1empress    时间: 2007-9-29 23:17
提示: 作者被禁止或删除 内容自动屏蔽
作者: Dr.BT    时间: 2007-9-29 23:19
原帖由 1empress 于 2007-9-29 23:17 发表
扣肉以前 sse都是64bit的

sse2指令又没变过,只不过cpu处理的时候这样来一下罢了
k8就是这样处理的
p4好像不是哦:shifty:
作者: Ricepig    时间: 2007-9-29 23:19
原帖由 Dr.BT 于 2007-9-29 23:11 发表

sse当然可以直接128bit
否则c2d怎么玩转的,k10怎么玩转的
sse的确需要从架构上去看的
现在两家公司最新的产品都根本不需要拆分了
以前是没办法,现在么:whistling:
早期说的不能处理80bit你理解错了吧 ...

IA-32 Intel Architecture Optimization Reference Manual 2-56页
"x87 supports 80-bit precision, double extended floating point.
Streaming SIMD Extensions support a maximum of 32-bit
precision, and Streaming SIMD Extensions 2 supports a maximum
of 64-bit precision."
所以我觉得你理解错了,所谓的128bit并不是128bit精度,而是两个64bit精度的运算,用一个指令算完吧

[ 本帖最后由 Ricepig 于 2007-9-29 23:20 编辑 ]
作者: 紫色    时间: 2007-9-29 23:19
请问:sse的128位能直接支持IEEE X_floating吗?
这问题也就是: sse能否在单周期完成两个128位的x_floating格式浮点数相乘?
如果是,那么确实是一大优势,将x87的80位浮点精度提高到128位。

恐怕不大可能。那就不是simd,而是真128位浮点了。

[ 本帖最后由 紫色 于 2007-9-29 23:27 编辑 ]
作者: Ricepig    时间: 2007-9-29 23:21
原帖由 紫色 于 2007-9-29 23:19 发表
请问:sse的128位能直接支持IEEE X_floating吗?
也就是直接能否支持128位浮点操作?单周期是否能完成128位的x_floating浮点相乘?
如果是,那么这确实是sse的一大优势。将x87的80浮点精度提高到128位。

我 ...

目前从Intel的手册上来看,SSE2的最大精度是64bit
作者: Ricepig    时间: 2007-9-29 23:27
要看SSE的威力,可以看这里http://blog.csdn.net/pengzhenwan ... /01/15/1483140.aspx
这是上次Intel多核优化大赛的一个报告,不算最快,但是已经比较快了,SSE的加速作用体现得比较充分,当然还有MKL和多核的威力.

[ 本帖最后由 Ricepig 于 2007-9-29 23:31 编辑 ]
作者: 紫色    时间: 2007-9-29 23:37
但是利用了双核优化?随便一个计算量大点的lapack程序,只要开了双核优化,速度上去个百分之几十很容易的。他所说的sse优化对速度提高的贡献大概多少?
谈到双核优化,到目前为止我的感觉是: 大多数情况下还不如关闭双核优化而使用openmp,速度提升更大。intel的c/fortran早就支持openmp甚至还改进为所谓cluster openmp。

[ 本帖最后由 紫色 于 2007-9-29 23:49 编辑 ]
作者: Ricepig    时间: 2007-9-29 23:39
原帖由 紫色 于 2007-9-29 23:37 发表
但是利用了双核优化?随便一个计算量大点的lapack程序,只要开了双核优化,速度上去40%很容易的。sse3对速度提高了多少还是未知?

你去那个网站看看详细的优化报告,每一个步骤提高了多少都清清楚楚
可以看到单独SSE提高了多少.
看看这个http://blog.csdn.net/flyingdog/archive/2007/01/21/1489183.aspx

[ 本帖最后由 Ricepig 于 2007-9-29 23:41 编辑 ]
作者: Edison    时间: 2007-9-29 23:57
虽然像基于SSE2这样的double precision指令集的运算器能透过特定的方法来跑quadruple precision,但是速度只怕会下降到1/30~1/300。
作者: Dr.BT    时间: 2007-9-30 00:01
原帖由 Ricepig 于 2007-9-29 23:19 发表

IA-32 Intel Architecture Optimization Reference Manual 2-56页
"x87 supports 80-bit precision, double extended floating point.
Streaming SIMD Extensions support a maximum of 32-bit
precisio ...

你不会连最基本的概念都没有吧
cell怎么处理dp的?
还不是32l,32h,最多效率下来一大截罢了
MULPD xmmreg1, xmmreg2
随便拿条乘法出来说说嘛
xmm能是两个dp为什么不是一个128?
64l,64h不就是128:huh:
谁说不能做了
作者: Edison    时间: 2007-9-30 00:05
原帖由 Dr.BT 于 2007-9-30 00:01 发表

你不会连最基本的概念都没有吧
cell怎么处理dp的?
还不是32l,32h,最多效率下来一大截罢了
MULPD xmmreg1, xmmreg2
随便拿条乘法出来说说嘛
xmm能是两个dp为什么不是一个128?
64l,64h不就是128:huh:  ...

SPE有专门的非流水线SI2D FP64 IEEE754单元。
作者: Ricepig    时间: 2007-9-30 00:54
原帖由 Dr.BT 于 2007-9-30 00:01 发表

你不会连最基本的概念都没有吧
cell怎么处理dp的?
还不是32l,32h,最多效率下来一大截罢了
MULPD xmmreg1, xmmreg2
随便拿条乘法出来说说嘛
xmm能是两个dp为什么不是一个128?
64l,64h不就是128:huh:  ...

两个64bit拼的128位浮点运算,属于偏软件实现,和本贴讨论的内容无关,而且拼起来的效率很低,不信你自己想想一个比较著名的问题"大数乘法"
Intel的文档说不支持128bit精度,某些人就是要嘴硬~~~
作者: 紫色    时间: 2007-9-30 02:31
看来也没有人来提供程序和数据,那就这样结束。感谢ricepig提供了对sse2优化的一个例子。非图形图像程序,simd如真能贡献10%的性能提升就令人刮目相看了。

顺便反驳一下前面3位高手:
1) p3/p4依靠sse压倒k7肯定是图形图像领域,数值计算领域这不可能。不要忘记p4中运行一条128位sse指令是两个周期,而x87是一个周期。考虑到simd的使用限制,科学计算程序在p4上舍x87而对sse优化只能吃亏。
2) 同样的理由,有人说athlonXp 1600+对athlon 1.4G的spec的相关部分测试性能提高是sse的功劳,不令人存疑吗?谁能解释sse哪里来的那种能耐?
3) 只有对core2/barcelona,数值计算程序才有进行sse优化的价值。“高手”们真要从网上拉程序拉数据,也要从这里入手吧?呵呵。那位拉了一个2001年中山大学bbs的程序,估计你也没有跑过从而不能提供运行时间等对比,大概只能在概念上对我有说服力吧?

sse提供了理论上2倍于x87的速度,但是simd的使用受数据关联和编译器优化能力的限制,也要受simd指令在整个计算量中的比重的影响。最终是什么结果,我会慢慢去测试。讨论到这里就可以了。封帖。

[ 本帖最后由 紫色 于 2007-9-30 03:35 编辑 ]
作者: bessel    时间: 2007-9-30 03:23
http://www1.ap.dell.com/content/topics/topic.aspx/ap/topics/power/zhcn/ps3q02_arrian?c=cn&l=zh&s=lca
图7及其文字说明,他们比较了p4处理器使用两种atlas的效率。



原帖由 紫色 于 2007-9-30 02:31 发表

看来也没有人来提供程序和数据,那就这样结束。感谢ricepig提供了对sse2优化的一个例子。非图形图像程序,simd如真能贡献10%的性能提升就令人刮目相看了。

顺便反驳一下前面3位兄弟:
1) p3/p4依靠sse压倒 ...

作者: Intelife    时间: 2007-9-30 07:38
原帖由 紫色 于 2007-9-30 02:31 发表
看来也没有人来提供程序和数据,那就这样结束。感谢ricepig提供了对sse2优化的一个例子。非图形图像程序,simd如真能贡献10%的性能提升就令人刮目相看了。

顺便反驳一下前面3位高手:
1) p3/p4依靠sse压倒 ...


晕倒,看了你这套理论,AMD都得给活活笑死!谁告诉你而x87能够一个周期搞完一条128位精度运算的?还有,128位是寄存器的宽度,不是指令的精度,你喷出的这套理论来看,你完全从根本上都不知道SSE为何物!SSE的能耐是定义了8个全新的128位寄存器,每个寄存器可以同时存放和处理4个单精度浮点数(每个32位长),进行128位精度运算时,在软件上完全可以利用这些寄存器和SIMD方式来高速实现,而不必再象X87那样去压堆栈,寄存器的操作是最省时最快的,特别是4个数一起做完的时候。所谓的SSE优化就是怎样让在这些寄存器的四个数,或者两个数通过一条指令同时做完运算,这样才能把原来需要4步的运算在一步内弄完。我拉那个程序给你看,是因为那个东西写得比较简单明白,画公仔都画出肠了,没想到你还是看不懂。
作者: 乌鸦2000    时间: 2007-9-30 07:58
提示: 作者被禁止或删除 内容自动屏蔽
作者: mxyou    时间: 2007-9-30 09:08
我现在才知道AMD绝对是可以死而无憾了,以前我一直是认为AMD可以坚持下去

AMD的国内人士都能说出SSE无用论,并且是好几天的刷版,既然SSE无用,就无用好了,这有什么好争的呢?
作者: mxyou    时间: 2007-9-30 09:11
还是说AMD中国在搞SSE无用论调查,不知道是不是全球同步

看来K11是打算不支持SSE,专心来搞SSE5的
作者: 晶晶守护神    时间: 2007-9-30 09:12
提示: 作者被禁止或删除 内容自动屏蔽
作者: 嘉蓝    时间: 2007-9-30 09:16
原帖由 晶晶守护神 于 2007-9-30 09:12 发表

乱说 从p3的  SSE 就是128bit

这个128bit是寄存器位宽。实际上sse不支持64位以上的操作数----------当然也没什么必要支持。
128位精度的浮点只在很小范围内有用,多数cpu也不直接提供支持。
作者: 晶晶守护神    时间: 2007-9-30 09:17
提示: 作者被禁止或删除 内容自动屏蔽
作者: 晶晶守护神    时间: 2007-9-30 09:19
提示: 作者被禁止或删除 内容自动屏蔽
作者: zicfy    时间: 2007-9-30 09:27
额...
被Interlife给忽悠住了~~~
作者: acqwer    时间: 2007-9-30 09:39
原帖由 紫色 于 2007-9-30 02:31 发表
看来也没有人来提供程序和数据,那就这样结束。感谢ricepig提供了对sse2优化的一个例子。非图形图像程序,simd如真能贡献10%的性能提升就令人刮目相看了。

顺便反驳一下前面3位高手:
1) p3/p4依靠sse压倒 ...

东西都有了,非要其他人给你详细指出吗?
Spec的189.lucas是fortran99编的质数判定,标准的数值运算,P4 1.4执行时间269,P3-s 1.4执行时间517,AthlonXP 1.4G执行时间369,Athlon 1.4G执行时间654,论X87性能肯定是Athlon=AthlonXP>P3>p4,你觉得这个结果的是如何产生的。
作者: 紫色    时间: 2007-9-30 11:53
原帖由 Intelife 于 2007-9-30 07:38 发表


晕倒,看了你这套理论,AMD都得给活活笑死!谁告诉你而x87能够一个周期搞完一条128位精度运算的?还有,128位是寄存器的宽度,不是指令的精度,你喷出的这套理论来看,你完全从根本上都不知道SSE为何物!SS ...


行了行了,别YY了。
x87是80位的。x87浮点计算是使用堆栈。128位sse指的当然是数据位, 一个指令操作4个32位或者2个64位。ok?

[ 本帖最后由 紫色 于 2007-9-30 12:16 编辑 ]
作者: 紫色    时间: 2007-9-30 12:05
原帖由 acqwer 于 2007-9-30 09:39 发表

东西都有了,非要其他人给你详细指出吗?
Spec的189.lucas是fortran99编的质数判定,标准的数值运算,P4 1.4执行时间269,P3-s 1.4执行时间517,AthlonXP 1.4G执行时间369,Athlon 1.4G执行时间654,论X87性 ...


我没有看到那个程序的源码,不敢说更多。
质数判定可能是整数编程吧?判定质数需要解析数论的知识从而引入浮点计算么?who knows?
我说了,最好有源码编一遍跑一遍,否则你只能去猜。

[ 本帖最后由 紫色 于 2007-9-30 12:17 编辑 ]
作者: acqwer    时间: 2007-9-30 12:16
原帖由 紫色 于 2007-9-30 12:05 发表


我没有看到那个程序的源码,不敢说更多。
质数判定可能是整数编程吧?判定质数需要解析数论的知识从而引入浮点计算么?who knows?
我说了,最好有源码,大家动手编一遍跑一遍,否则你只能去猜。

你当Spec的人是请注意文明用词啊,整数测试放在SpecFP里。
如果你要反驳,请拿出合理的解释,两倍以上的性能提升已经摆在这了,你认为是怎么来的?
作者: xxxyyy    时间: 2007-9-30 12:21
提示: 作者被禁止或删除 内容自动屏蔽
作者: _MyST_Spring    时间: 2007-9-30 12:39
AMD可以瞑目了,每次Intel推出SSE指令集的时候,AMD都pdpd的第一时间跟上。

如此看来,AMD真是浪费了无数的晶体管来做这种根本对性能提升无意义的事情啊
作者: Prescott    时间: 2007-9-30 14:32
晕死,随便来个简单的吧
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. float a[512][512], b[512][512], c;

  4. int main () {

  5.     srand(0);
  6.     for (int i=0; i < 512; i++){
  7.         for (int j = 0; j < 512; j++){
  8.             a[i][j] = (double)rand() / RAND_MAX;
  9.             b[i][j] = (double)rand() / RAND_MAX;
  10.         }
  11.     }

  12.     for (int N = 1; N < 10000; N++)
  13.     for (int i=0; i < 512; i++){
  14.         for (int j = 0; j < 512; j++){
  15.             c = a[i][j] + a[i][j] * b[i][j];
  16.         }
  17.     }
  18.     printf ("result of c is %fn", c);
  19.     return 0;
  20. }


  21. [test]$ g++ -O3 -mfpmath=387 main.cc -o a.gcc.387
  22. [test]$ g++ -O3 -mfpmath=sse -ftree-vectorize -ftree-vectorizer-verbose=5 main.cc -o a.gcc.sse
  23. main.cc:10: note: not vectorized: unhandled data-ref
  24. main.cc:18: note: not vectorized: live stmt not supported: D.3579_28 = a[i_78][j_79]
  25. main.cc:18: note: vectorized 0 loops in function.
  26. (笨笨的gcc,这么简单的循环居然都不会向量化)

  27. [test]$ icc -fast main.cc -o a.icc
  28. ipo: remark #11001: performing single-file optimizations
  29. ipo: remark #11005: generating object file /tmp/ipo_iccRoENV3.o
  30. main.cc(17): (col. 5) remark: LOOP WAS VECTORIZED.
  31. (还是icc聪明)

  32. [test]$ time ./a.gcc.387
  33. result of c is 1.596053

  34. real    0m3.545s
  35. user    0m3.540s
  36. sys     0m0.004s

  37. [test]$ time ./a.gcc.sse
  38. result of c is 1.596053

  39. real    0m3.454s
  40. user    0m3.451s
  41. sys     0m0.003s

  42. [test]$ time ./a.icc
  43. result of c is 1.596053

  44. real    0m0.766s
  45. user    0m0.765s
  46. sys     0m0.001s
复制代码


[ 本帖最后由 Prescott 于 2007-9-30 14:57 编辑 ]
作者: _MyST_Spring    时间: 2007-9-30 15:01
原帖由 Prescott 于 2007-9-30 14:32 发表
晕死,随便来个简单的吧
#include
#include

float a[512][512], b[512][512], c;

int main () {

    srand(0);
    for (int i=0; i < 512; i++){
        for (int j = 0; j < 512; j++){
    ...


老P又不厚道了一回
作者: Prescott    时间: 2007-9-30 15:09
原帖由 _MyST_Spring 于 2007-9-30 15:01 发表


老P又不厚道了一回

:unsure:

又怎么不厚道了?
作者: 晶晶守护神    时间: 2007-9-30 15:12
提示: 作者被禁止或删除 内容自动屏蔽
作者: _MyST_Spring    时间: 2007-9-30 15:19
原帖由 Prescott 于 2007-9-30 15:09 发表

:unsure:

又怎么不厚道了?


也不给人楼主留点face啊。。
作者: 紫色    时间: 2007-9-30 15:30
原帖由 Prescott 于 2007-9-30 14:32 发表
晕死,随便来个简单的吧
#include
#include

float a[512][512], b[512][512], c;

int main () {

    srand(0);
    for (int i=0; i < 512; i++){
        for (int j = 0; j < 512; j++){
    ...



8错的例子。不过只不过是比较了gcc和icc。
你的程序看似循环了512*512次,但每次循环都是独立的对c赋值。其实c最终就等于a(512,512)+a(512,512)*b(512,512)?聪明点的编译器把它优化到运行时间0.0001秒都有可能。
对icc,有其他优化选项完全相同,仅有浮点单元是sse/x87的一点区别的数据提供吗?

PS:能否说一下cpu是啥。类似的程序我跑过不少,p4上加了sse优化,(以下缩水)。

c = a[j] + a[j] * b[j]这种表达式利用不了sse。也许icc能利用sse每次计算两个循环,如果不能保证这一点就改善一下你的代码,让它好利用sse。

[ 本帖最后由 紫色 于 2007-9-30 16:27 编辑 ]
作者: Prescott    时间: 2007-9-30 16:19
原帖由 紫色 于 2007-9-30 15:30 发表


8错的例子。不过只不过是比较了gcc和icc。
对icc,有其他优化选项完全相同,仅有浮点单元是sse/x87的一点区别的数据提供吗?


PS:能否说一下cpu是啥。类似的程序我跑过不少,p4上加了sse优化,速度还 ...


  1. [~]$ uname -a
  2. Linux xxxxxxxx 2.6.18-8.el5 #1 SMP Fri Jan 26 14:15:14 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

  3. [~]$ cat /proc/cpuinfo
  4. ...
  5. model name      : Intel(R) Core(TM)2 CPU          6700  @ 2.66GHz
  6. ...
复制代码


不好意思,gcc很笨只能生成标量的SSE,icc不支持在64bit环境下生成x87代码。
作者: Prescott    时间: 2007-9-30 17:21
原帖由 紫色 于 2007-9-30 15:30 发表



8错的例子。不过只不过是比较了gcc和icc。
你的程序看似循环了512*512次,但每次循环都是独立的对c赋值。其实c最终就等于a(512,512)+a(512,512)*b(512,512)?聪明点的编译器把它优化到运行时间0.0001 ...


稍微修改一下程序,满足你一下:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. float a[512][512], b[512][512], c[512][512], d = 0;

  4. int main () {

  5.     int i,j,N;

  6.     srand(0);
  7.     for (i = 0; i < 512; i++){
  8.         for (j = 0; j < 512; j++){
  9.             a[i][j] = ((float)rand() / RAND_MAX) - 0.5;
  10.             b[i][j] = ((float)rand() / RAND_MAX) - 0.5;
  11.             c[i][j] = 0;
  12.         }
  13.     }

  14.     for (N = 1; N < 100000; N++)
  15.     for (i = 0; i < 512; i++){
  16.         for (j = 0; j < 512; j++ ){
  17.             c[i][j] = c[i][j] + a[i][j] * b[i][j];
  18.         }
  19.     }

  20.     i = rand() % 512;
  21.     j = rand() % 512;
  22.     printf ("result of c[%d][%d] is %fn", i, j, c[i][j]);
  23.     return 0;
  24. }


  25. [test]$ g++ -O3 -mfpmath=387 main.cc -o a.gcc.387

  26. [test]$ g++ -O3 -mfpmath=sse -ftree-vectorize -ftree-vectorizer-verbose=5 main.cc -o a.gcc.sse
  27. main.cc:12: note: not vectorized: unhandled data-ref
  28. main.cc:21: note: dependence distance  = 0.
  29. main.cc:21: note: accesses have the same alignment.
  30. main.cc:21: note: dependence distance modulo vf == 0 between c[i_89][j_91] and c[i_89][j_91]
  31. main.cc:21: note: dependence distance  = 0.
  32. main.cc:21: note: accesses have the same alignment.
  33. main.cc:21: note: dependence distance modulo vf == 0 between c[i_89][j_91] and c[i_89][j_91]
  34. main.cc:21: note: LOOP VECTORIZED.
  35. main.cc:21: note: vectorized 1 loops in function.

  36. [test]$ icc -fast main.cc -o a.icc.sse
  37. ipo: remark #11001: performing single-file optimizations
  38. ipo: remark #11005: generating object file /tmp/ipo_iccjm6Zar.o
  39. main.cc(20): (col. 5) remark: LOOP WAS VECTORIZED.

  40. [test]$ time ./a.gcc.387
  41. result of c[25][391] is -297.068634
  42. real    0m35.912s
  43. user    0m35.903s
  44. sys     0m0.004s

  45. [test]$ time ./a.gcc.sse
  46. result of c[25][391] is -297.068634
  47. real    0m17.791s
  48. user    0m17.783s
  49. sys     0m0.005s

  50. [test]$ time ./a.icc.sse
  51. result of c[25][391] is -297.068634
  52. real    0m17.041s
  53. user    0m17.035s
  54. sys     0m0.003s
复制代码

作者: slice    时间: 2007-9-30 19:23
:loveliness:
扯那么多干嘛,AMD的U主板bios有个功能可以关掉SSE支持。intel就不知道如何屏蔽了。
如果你是用的X2之类的,大可以关掉SSE回到远古时代,看看会不会是世界末日。
结果是不会,还好Windows不是OSX,没SSE照样工作。倒是KMPlayer直接罢工了,不怕,用WMP11,放个720P的WMV不过也就CPU占用高了10%多而已。
TS的倒是高了%好几十,不过可能是用WMP没SSE视频加速给弄没了吧,倒不是SSE的作用。
在没有SSE的日子里。你才能体会到SSE的好处。
所以我决定再体验三天没有SSE的日子,大家说我能坚持3天不:loveliness: 。有句话不是说失去了才懂得珍惜么。
作者: acqwer    时间: 2007-9-30 19:45
原帖由 slice 于 2007-9-30 19:23 发表
:loveliness:
扯那么多干嘛,AMD的U主板bios有个功能可以关掉SSE支持。intel就不知道如何屏蔽了。
如果你是用的X2之类的,大可以关掉SSE回到远古时代,看看会不会是世界末日。
结果是不会,还好Windows不是 ...

跑个3dmarks看看。
作者: Intelife    时间: 2007-9-30 19:47
原帖由 slice 于 2007-9-30 19:23 发表
:loveliness:
扯那么多干嘛,AMD的U主板bios有个功能可以关掉SSE支持。intel就不知道如何屏蔽了。
如果你是用的X2之类的,大可以关掉SSE回到远古时代,看看会不会是世界末日。
结果是不会,还好Windows不是 ...


只关掉一个核心上的SSE,还是关掉了两个?
作者: NehalemSunK11    时间: 2007-9-30 19:57
:lol: 什么显卡,跑个OPENGL游戏看看
作者: slice    时间: 2007-9-30 20:33
原帖由 acqwer 于 2007-9-30 19:45 发表

跑个3dmarks看看。


试了下Mark03。
My God!跑还是能跑,结果有点匪夷所思!放720P的WMVCPU也就30%多变成40%多而已。没想到Mark03会这样子。谁能tell me why?
关SSE简直就是超级幻灯片啊,92分。不关是720分。w00t) 问题出在哪里,Mark03发现没SSE脑袋秀逗了?
作者: viewlg    时间: 2007-9-30 20:44
以前用sse一直是处理视频图象 没搞过数值计算 随便试了下单精度的计算

var                 s,sbasic:single;
        param1,param2,param3:single;
                   tb,te,tf:int64;
begin
   sbasic:=1.0;
   param1:=19.12;
   param2:=19.13;
   param3:=0.1;

   queryperformancefrequency(tf);
   queryperformanceCounter(tb);

   //包括加/乘/除各一次 循环1000万次并对前次结果依赖 不会产生优化

   //x87指令
   Asm
    mov ecx, 10000000
    fld s
  @loop:
    fmul param1
    fdiv param2
    fadd param3
    dec ecx
    jnz @loop
    fstp s
   end;
   queryperformanceCounter(te);

   //输出时间消耗
   memo1.Lines.Append(format('x87 %f ms %f  ', [(te-tb)/tf*1000,s]) );

   queryperformanceCounter(tb);

   //SSE指令
   Asm
     mov ecx, 10000000
     movss xmm0, sbasic
   @loop:
     movss xmm1, param1
     movss xmm2, param2
     movss xmm3, param3
     mulss xmm0, xmm1
     divss xmm0, xmm2
     addss xmm0, xmm3
     dec  ecx
     jnz  @loop
     movss s, xmm0
   end;
   queryperformanceCounter(te);

      //输出时间消耗
   memo1.Lines.Append(format('SSE %f ms %f  ', [(te-tb)/tf*1000,s]) );

测试结果
x87 170.98 ms 191.33  
SSE 93.73 ms 191.32  

证明即使是不使用SIMD优化,只是替代x87浮点指令为sse指令就能获得接近一倍的速度提高.

但是可以发现, 2者的计算结果有一定的差异. 而双精度的计算结果是191.30,计算结果上反而是SSE更加精确. 所以在浮点计算时采用sse那是很有效果的,如果考虑到SIMD的并行计算,那提高不是一点半点啊.

注: 手头的 delphi 7只支持 sse,不支持sse2 ,没法试双精度了.我想应该区别不大.因为 sse里不管是使用
ps后缀并行计算4个还是采用ss后缀单独计算一个速度是没区别的.

[ 本帖最后由 viewlg 于 2007-9-30 20:46 编辑 ]
作者: the_god_of_pig    时间: 2007-9-30 20:45
SIMD无用论,竟然这么长时间了还有人在YY(_(

好吧,LZ永远是对的,IBM,Intel,AMD都是250,就LZ有远见,发现了客观事实的真理,佩服,在下一定铭记在心:huh:
作者: viewlg    时间: 2007-9-30 20:54
原帖由 slice 于 2007-9-30 20:33 发表


试了下Mark03。
My God!跑还是能跑,结果有点匪夷所思!放720P的WMVCPU也就30%多变成40%多而已。没想到Mark03会这样子。谁能tell me why?
关SSE简直就是超级幻灯片啊,92分。不关是720分。w00t) 问题出 ...



SSE的Sqrt计算比FP的Sqrt计算快10倍以上(单运算而不考虑simd,考虑simd则是接近50倍).而开方计算是3d驱动里最常见的计算.
作者: acqwer    时间: 2007-9-30 21:00
原帖由 slice 于 2007-9-30 20:33 发表


试了下Mark03。
My God!跑还是能跑,结果有点匪夷所思!放720P的WMVCPU也就30%多变成40%多而已。没想到Mark03会这样子。谁能tell me why?
关SSE简直就是超级幻灯片啊,92分。不关是720分。w00t) 问题出 ...

03也就罢了,05、06没SSE根本不让你跑。
作者: wxm    时间: 2007-9-30 21:03
lz真像AMD-FANS 总要弄个xx论大肆批斗啊
嫌论坛还不够慢啊..
作者: Edison    时间: 2007-9-30 21:16
SSE/SSE2指令集并不是只有SIMD运算的扩展,还有一些load/store方面的指令,能达到提高UCWC的效率。
作者: Intelife    时间: 2007-9-30 21:21
原帖由 slice 于 2007-9-30 20:33 发表


试了下Mark03。
My God!跑还是能跑,结果有点匪夷所思!放720P的WMVCPU也就30%多变成40%多而已。没想到Mark03会这样子。谁能tell me why?
关SSE简直就是超级幻灯片啊,92分。不关是720分。w00t) 问题出 ...


放wmv大部份用的是MMX,你关掉这个就可能根本不让你跑了。
作者: 紫色    时间: 2007-9-30 21:54
找了台双Xeon的机器,跑prescutt的程序。gcc版本是4.3.0pre

运行时间竟然是6m40s w00t) ,我还以为死机了呢。
[19:50:08][~]$g++ -O3 -mfpmath=387 1.c -o a.out.387
[19:52:15][~]$time ./a.out.387
result of c[25][391] is -297.068634

real    6m38.561s
user    6m38.010s
sys     0m0.030s

[20:17:01][~]$g++ -O3 -msse2 -mfpmath=sse 1.c -o a.out.sse
[20:17:50][~]$time ./a.out.sse
result of c[25][391] is -297.068634

real    6m43.477s
user    6m39.830s
sys     0m1.130s

=======================
[20:40:03][~]$gcc --version
gcc (GCC) 4.3.0 20070921 (experimental)
Copyright (C) 2007 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。

==========================
processor       : 3
vendor_id       : GenuineIntel
cpu family      : 15
model           : 2
model name      : Intel(R) Xeon(TM) CPU 2.40GHz
stepping        : 7
cpu MHz         : 2394.804
cache size      : 512 KB
physical id     : 3
siblings        : 2
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm
bogomips        : 4784.12
作者: colo    时间: 2007-9-30 22:25
seti优化程序的各种sse版本 :lol:

http://www.equn.com/forum/thread-16358-1-1.html
作者: YsMilan    时间: 2007-9-30 22:45
楼上也玩分布式啊w00t)

SETI用SSE优化效果实在是,没说的



[ 本帖最后由 YsMilan 于 2007-9-30 22:46 编辑 ]
作者: Prescott    时间: 2007-9-30 22:57
原帖由 紫色 于 2007-9-30 21:54 发表
找了台双Xeon的机器,跑prescutt的程序。gcc版本是4.3.0pre

运行时间竟然是6m40s w00t) ,我还以为死机了呢。
[19:50:08][~]$g++ -O3 -mfpmath=387 1.c -o a.out.387
[19:52:15][~]$time ./a.out.387
resu ...


六分多钟很奇怪吗?:lol: :lol: :lol:
作者: NehalemSunK11    时间: 2007-9-30 23:25
原帖由 Prescott 于 2007-9-30 17:21 发表


稍微修改一下程序,满足你一下:

#include
#include

float a[512][512], b[512][512], c[512][512], d = 0;

int main () {

    int i,j,N;

    srand(0);
    for (i = 0; i < 512; i++ ...


用P大的代码试了一下:loveliness:
结果如下:

gogo@no1-debian:~/test$ g++ -O3 -mfpmath=387 sse.cc -o a.gcc.387
gogo@no1-debian:~/test$ time ./a.gcc.387
result of c[25][391] is -297.068634

real    8m29.681s
user    8m28.160s
sys     0m0.212s
gogo@no1-debian:~/test$ g++ -O3 -mfpmath=sse -ftree-vectorize -ftree-vectorizer-verbose=5 sse.cc -o a.gcc.sse
sse.cc:1: warning: SSE instruction set disabled, using 387 arithmetics

sse.cc:12: note: not vectorized: unhandled data-ref
sse.cc:21: note: not vectorized: no vectype for stmt: D.3208_38 = c[i_15][j_88] scalar_type: float
sse.cc:21: note: vectorized 0 loops in function.

//照P大的参数居然优化不成功,加了对应CPU的参数就好了
gogo@no1-debian:~/test$ g++ -O3 -mfpmath=sse  -march=athlon-xp  -ftree-vectorize -ftree-vectorizer-verbose=5 sse.cc -o a.gcc.sse

sse.cc:12: note: not vectorized: unhandled data-ref
sse.cc:21: note: dependence distance  = 0.
sse.cc:21: note: accesses have the same alignment.
sse.cc:21: note: dependence distance modulo vf == 0 between c[i_90][j_92] and c[i_90][j_92]
sse.cc:21: note: dependence distance  = 0.
sse.cc:21: note: accesses have the same alignment.
sse.cc:21: note: dependence distance modulo vf == 0 between c[i_90][j_92] and c[i_90][j_92]
sse.cc:21: note: LOOP VECTORIZED.
sse.cc:21: note: vectorized 1 loops in function.
gogo@no1-debian:~/test$ time ./a.gcc.sse
result of c[25][391] is -297.068634

real    5m33.425s
user    5m32.317s
sys     0m0.160s
gogo@no1-debian:~/test$
作者: potomac    时间: 2007-9-30 23:29
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 POPPUR爱换 (https://we.poppur.com/) Powered by Discuz! X3.4