Optimizations of JT9 and JT65 decoders; change clock in timer routine.

Both decoders now have slightly better performance and faster
execution.  The rare "duplicate decodes" in JT9 were eliminated.
On Windows, at least, calls to f90 routine system_clock() do not
provide correct wall time increments.  Changed to using secnds()
instead.


git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@4571 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2014-10-30 19:29:16 +00:00
parent 7680cb3c75
commit d9bc8f5dff
5 changed files with 57 additions and 70 deletions

View File

@ -21,7 +21,6 @@ subroutine decoder(ss,id2)
common/tracer/limtrace,lu common/tracer/limtrace,lu
save save
call system_clock(iclock0,iclock_rate,iclock_max) !###
nfreqs0=0 nfreqs0=0
nfreqs1=0 nfreqs1=0
ndecodes0=0 ndecodes0=0
@ -84,13 +83,13 @@ subroutine decoder(ss,id2)
dblim=db(864.0/nsps8) - 26.2 dblim=db(864.0/nsps8) - 26.2
do nqd=1,0,-1 do nqd=1,0,-1
limit=1000 limit=5000
ccflim=4.0 ccflim=3.0
red2lim=1.6 red2lim=1.6
schklim=2.2 schklim=2.2
if(ndepth.eq.2) then if(ndepth.eq.2) then
limit=10000 limit=10000
ccflim=3.5 ccflim=2.7
endif endif
if(ndepth.ge.3 .or. nqd.eq.1) then if(ndepth.ge.3 .or. nqd.eq.1) then
limit=100000 limit=100000
@ -135,17 +134,15 @@ subroutine decoder(ss,id2)
freq,drift,schk,i1SoftSymbols) freq,drift,schk,i1SoftSymbols)
call timer('softsym ',1) call timer('softsym ',1)
! write(71,3001) nqd,i,f,fpk,ccfred(i),red2(i),schk sync=(syncpk+1)/4.0
!3001 format(2i6,2f8.1,3f6.1) if(maxval(i1SoftSymbols).eq.0) cycle
! call flush(71) if(nqd.eq.1 .and. ((sync.lt.0.5) .or. (schk.lt.2.0))) cycle
if(nqd.ne.1 .and. ((sync.lt.1.0) .or. (schk.lt.schklim))) cycle
if(schk.lt.schklim) cycle
call timer('decode9 ',0) call timer('decode9 ',0)
call decode9(i1SoftSymbols,limit,nlim,msg) call decode9(i1SoftSymbols,limit,nlim,msg)
call timer('decode9 ',1) call timer('decode9 ',1)
sync=(syncpk+1)/4.0
if(sync.lt.0.0 .or. snrdb.lt.dblim-2.0) sync=0.0 if(sync.lt.0.0 .or. snrdb.lt.dblim-2.0) sync=0.0
nsync=sync nsync=sync
if(nsync.gt.10) nsync=10 if(nsync.gt.10) nsync=10
@ -183,7 +180,7 @@ subroutine decoder(ss,id2)
call jt65a(dd,npts65,newdat,nutc,nf1,nf2,nfqso,ntol65,nagain,ndecoded) call jt65a(dd,npts65,newdat,nutc,nf1,nf2,nfqso,ntol65,nagain,ndecoded)
endif endif
!### JT65 is not yet producing info for nsynced, ndecoded. ! JT65 is not yet producing info for nsynced, ndecoded.
800 write(*,1010) nsynced,ndecoded 800 write(*,1010) nsynced,ndecoded
1010 format('<DecodeFinished>',2i4) 1010 format('<DecodeFinished>',2i4)
call flush(6) call flush(6)

View File

@ -1,4 +1,4 @@
subroutine demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow) subroutine demod64a(s3,nadd,afac1,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
! Demodulate the 64-bin spectra for each of 63 symbols in a frame. ! Demodulate the 64-bin spectra for each of 63 symbols in a frame.
@ -10,23 +10,16 @@ subroutine demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
! mr2prob probability that mr2sym was the transmitted value ! mr2prob probability that mr2sym was the transmitted value
implicit real*8 (a-h,o-z) implicit real*8 (a-h,o-z)
real*4 s3(64,63) real*4 s3(64,63),afac1
real*8 fs(64) real*8 fs(64)
integer mrsym(63),mrprob(63),mr2sym(63),mr2prob(63) integer mrsym(63),mrprob(63),mr2sym(63),mr2prob(63)
! common/mrscom/ mrs(63),mrs2(63)
if(nadd.eq.-999) return if(nadd.eq.-999) return
afac=1.1 * float(nadd)**0.64 afac=afac1 * float(nadd)**0.64
scale=255.999 scale=255.999
! Compute average spectral value ! Compute average spectral value
sum=0. ave=sum(s3)/(64.*63.)
do j=1,63
do i=1,64
sum=sum+s3(i,j)
enddo
enddo
ave=sum/(64.*63.)
i1=1 !Silence warning i1=1 !Silence warning
i2=1 i2=1
@ -57,17 +50,13 @@ subroutine demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
mr2sym(j)=i2-1 mr2sym(j)=i2-1
mrprob(j)=scale*p1 mrprob(j)=scale*p1
mr2prob(j)=scale*p2 mr2prob(j)=scale*p2
! mrs(j)=i1
! mrs2(j)=i2
enddo enddo
sum=0.
nlow=0 nlow=0
do j=1,63 do j=1,63
sum=sum+mrprob(j)
if(mrprob(j).le.5) nlow=nlow+1 if(mrprob(j).le.5) nlow=nlow+1
enddo enddo
ntest=sum/63 ntest=sum(mrprob)/63.0
return return
end subroutine demod64a end subroutine demod64a

View File

@ -1,4 +1,7 @@
subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv) subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
!subroutine extract(s3,nadd,nbirdie,afac1,xlambda,ncount,nhist,decoded, &
! ltext,nbmkv,ntest)
! Input: ! Input:
! s3 64-point spectra for each of 63 data symbols ! s3 64-point spectra for each of 63 data symbols
@ -15,30 +18,35 @@ subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
real s3(64,63) real s3(64,63)
character decoded*22 character decoded*22
integer era(51),dat4(12),indx(64) integer dat4(12)
integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63) integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63)
logical nokv,ltext logical nokv,ltext
data nokv/.false./,nsec1/0/ data nokv/.false./,nsec1/0/
save save
nbirdie=7
npct=40
afac1=10.1
xlambda=8.0
nbmkv=0 nbmkv=0
nfail=0 nfail=0
decoded=' '
call pctile(s3,4032,npct,base)
s3=s3/base
! Get most reliable and second-most-reliable symbol values, and their ! Get most reliable and second-most-reliable symbol values, and their
! probabilities ! probabilities
1 call demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow) 1 call demod64a(s3,nadd,afac1,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
if(ntest.lt.50 .or. nlow.gt.20) then if(ntest.lt.100) then
ncount=-999 !Flag and reject bad data ncount=-999 !Flag and reject bad data
go to 900 go to 900
endif endif
call chkhist(mrsym,nhist,ipk) !Test for birdies and QRM
if(nhist.ge.20) then call chkhist(mrsym,nhist,ipk) !Test for birdies and QRM
if(nhist.ge.nbirdie) then
nfail=nfail+1 nfail=nfail+1
call pctile(s3,4032,50,base) call pctile(s3,4032,npct,base)
do j=1,63 s3(ipk,1:63)=base
s3(ipk,j)=base
enddo
if(nfail.gt.30) then if(nfail.gt.30) then
decoded=' ' decoded=' '
ncount=-1 ncount=-1
@ -47,42 +55,27 @@ subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
go to 1 go to 1
endif endif
call graycode65(mrsym,63,-1) call graycode65(mrsym,63,-1) !Remove gray code and interleaving
call interleave63(mrsym,-1) call interleave63(mrsym,-1) !from most reliable symbols
call interleave63(mrprob,-1) call interleave63(mrprob,-1)
! Decode using Berlekamp-Massey algorithm ! Decode using Berlekamp-Massey algorithm
nemax=30 !Max BM erasures call timer('rs_decod',0)
call indexx(63,mrprob,indx) call rs_decode(mrsym,0,0,dat4,ncount)
do i=1,nemax call timer('rs_decod',1)
j=indx(i)
if(mrprob(j).gt.120) then
ne2=i-1
go to 2
endif
era(i)=j-1
enddo
ne2=nemax
2 decoded=' '
do nerase=0,ne2,2
call rs_decode(mrsym,era,nerase,dat4,ncount)
if(ncount.ge.0) then if(ncount.ge.0) then
call unpackmsg(dat4,decoded) call unpackmsg(dat4,decoded)
if(iand(dat4(10),8).ne.0) ltext=.true. if(iand(dat4(10),8).ne.0) ltext=.true.
nbmkv=1 nbmkv=1
go to 900 go to 900
endif endif
enddo
! Berlekamp-Massey algorithm failed, try Koetter-Vardy ! Berlekamp-Massey algorithm failed, try Koetter-Vardy
if(nokv) go to 900 if(nokv) go to 900
maxe=8 !Max KV errors in 12 most reliable symbols maxe=8 !Max KV errors in 12 most reliable symbols
! xlambda=12.0 call graycode65(mr2sym,63,-1) !Remove gray code and interleaving
xlambda=7.99 call interleave63(mr2sym,-1) !from second-most-reliable symbols
call graycode65(mr2sym,63,-1)
call interleave63(mr2sym,-1)
call interleave63(mr2prob,-1) call interleave63(mr2prob,-1)
nsec1=nsec1+1 nsec1=nsec1+1
@ -92,8 +85,8 @@ subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
call flush(22) call flush(22)
call timer('kvasd ',0) call timer('kvasd ',0)
! TODO G4WJS: Take out '-q' argument once kvasd 1.12 is available for Mac and in the repo ! TODO G4WJS: Take out '-q' argument once kvasd 1.12 is available for
! where CMake fetches it from. ! Mac and in the repo where CMake fetches it from.
#ifdef WIN32 #ifdef WIN32
iret=system('""'//trim(exe_dir)//'/kvasd" -q >dev_null"') iret=system('""'//trim(exe_dir)//'/kvasd" -q >dev_null"')
! iret=system('""'//trim(exe_dir)//'/kvasd" kvasd.dat >dev_null"') ! iret=system('""'//trim(exe_dir)//'/kvasd" kvasd.dat >dev_null"')
@ -101,6 +94,7 @@ subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
iret=system('"'//trim(exe_dir)//'/kvasd" -q >/dev/null') iret=system('"'//trim(exe_dir)//'/kvasd" -q >/dev/null')
! iret=system('"'//trim(exe_dir)//'/kvasd" kvasd.dat >/dev/null') ! iret=system('"'//trim(exe_dir)//'/kvasd" kvasd.dat >/dev/null')
#endif #endif
call timer('kvasd ',1) call timer('kvasd ',1)
if(iret.ne.0) then if(iret.ne.0) then
if(.not.nokv) write(*,1000) iret if(.not.nokv) write(*,1000) iret

View File

@ -34,7 +34,10 @@ subroutine symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk, &
enddo enddo
call chkss2(ss2,freq,drift,schk) call chkss2(ss2,freq,drift,schk)
if(schk.lt.2.0) go to 900 if(schk.lt.2.0) then
i1SoftSymbolsScrambled=0
go to 900
endif
ss=0. ss=0.
sig=0. sig=0.

View File

@ -38,7 +38,9 @@ subroutine timer(dname,k)
on(n)=.true. on(n)=.true.
! call system_clock(icount,irate) ! call system_clock(icount,irate)
! ut0(n)=float(icount)/irate ! ut0(n)=float(icount)/irate
call cpu_time(ut0(n)) ! call cpu_time(ut0(n))
ut0(n)=secnds(0.0)
ncall(n)=ncall(n)+1 ncall(n)=ncall(n)+1
if(ncall(n).gt.1.and.nlevel(n).ne.level) then if(ncall(n).gt.1.and.nlevel(n).ne.level) then
nlevel(n)=-1 nlevel(n)=-1
@ -53,7 +55,9 @@ subroutine timer(dname,k)
on(n)=.false. on(n)=.false.
! call system_clock(icount,irate) ! call system_clock(icount,irate)
! ut1=float(icount)/irate ! ut1=float(icount)/irate
call cpu_time(ut1) ! call cpu_time(ut1)
ut1=secnds(0.0)
ut(n)=ut(n)+ut1-ut0(n) ut(n)=ut(n)+ut1-ut0(n)
endif endif
level=level-1 level=level-1