向量化计算出现的异常问题
-
drivev.f: program NEKTON integer,parameter::N=24 real,dimension(N,N)::a,c real,dimension(N,N)::b integer::start,finish call system_clock(start) call mxf8(a,N,b,N,c,N) call system_clock(finish) write(*,*) 't -s ',(finish-start)/10000. end
mxm_stdv.f: subroutine mxf8(a,n1,b,n2,c,n3) integer,parameter::N=24 real::a(n1,N),b(N,n3),c(n1,n3) integer::i,j,k,error real::kt,x call random_seed() do k=1,100000 do j=1,N do i=1,n1 call random_number(x) a(i,j)=x enddo enddo do j=1,n3 do i=1,N call random_number(x) b(i,j)=x enddo enddo c=0 call my_slave(a,%val(n1),b,%val(n2),c,%val(n3)) enddo end
my_slavev.c: #include<stdio.h> #include<string.h> #include"simd.h" #define N 24 #define NL24U24 576 float *pa; float *pb; float *pc; int n11; int n22; int n33; void my_slave_(float* a,int n1,float* b,int n2,float* c,int n3) { int i,j,k; int ind,lima,limb,limc; float tmp[4]; floatv4 fva,fvb,fvc,fvt; pa=a; pb=b; pc=c; n11=n1; n22=n2; n33=n3; int dd; if(n1 == n2) { for(j=0;j<n2;j++) { for(i=0;i<N;i++) { limb=N*j; limc=n1*j; lima=(i+1)*n1; simd_loade(fvb,b+limb+i); for(k=i*n1,ind=0;k<lima;k+=4,ind+=4) { simd_load(fva,a+k); fvc=fva*fvb; simd_load(fvt,c+limc+ind); fvc+=fvt; simd_store(fvc,c+limc+ind); //simd_store(fvc,&tmp[0]); //memcpy(c+limc+ind,tmp,16); } } } } return; }
testv.sh: #!/bin/bash sw5f90 -host -I/usr/sw-mpp/mpi2/include -c drivev.f sw5f90 -host -I/usr/sw-mpp/mpi2/include -c mxm_stdv.f sw5cc -host -msimd -O3 -c my_slavev.c #mpif90 drive.o athread_set_num_threads.o athread_get_num_threads.o mxm_std.o my_slave.o slave.o slave8.o DMA_getid.o reply_wait.o -L/path/to/xMath -lxMath -o exxO mpif90 drivev.o mxm_stdv.o my_slavev.o -o exxv
这是我的程序脚本和文件,然后我出现了一个问题。如果我的程序的变量申明为real,float(单精度浮点数时),这个程序的运行时间才30秒,当我把程序改成double precision,double(双精度浮点数时)整个程序运行时间要10多分钟,问题在simd_store为什么会这么慢啊?这个向量化是不是有什么问题啊。
-
1.不能单靠您现在测试就怀疑是simd_store的问题,建议分析一下程序,设计更多测试来确定具体的原因,注意测试的时候要保证测试环境是一致的,比如提交任务的节点。
2.如果怀疑double类型的simd_store实现不好,可以改写成嵌汇编:
#define my_simdstore(va,addr) asm volatile("vldd %0,0(%1)" : “=r”(va) : "r"(addr))
试试。
-
如果性能差别有这么大你可能需要确定一下你是不是每次提交时bsub都带了-b参数。
-
@夜深忽梦少年事 您好我提交的时候是有-b参数的。。可是我好像发现fortran编译器对double类型并没有对界处理啊。。。当我尝试使用 !$ align_symbol(symbol,32) 对数组处理一下,速度又正常了,可是这个声明只能用在common啊。。
-
@大笨象 是的,fortran手动向量化是申威特色功能,问题应该会比较多,毕竟ICC也不支持fortran手动向量化。
-
@夜深忽梦少年事 手动向量化?文档上也没这个东西噢,那我该怎么处理啊。。。我能不能在编译时让数组都自动对界啊 好像c一样。。
-
@大笨象 我的印象是
sw5f90 -slave -msimd -mp
的话定长数组可以自动对齐。
-
@popo 您好,请问您提供的这个嵌汇编语句可以在主核上使用吗?
我试了一下这个语句,编译的时候报了
Error: inappropriate arguments for opcode `vldd'
这样的错误
-
@caiji 这个没测试过 ,但是手册应该由官方的向量化原语
-
@caiji 原因是主核上有浮点寄存器和整数寄存器的区别,可以试试:
#define my_simdstore(va,addr) asm volatile("vldd %0,0(%1)" : “=f”(va) : "r"(addr))
=f
表示操作数是浮点寄存器。