r6732 - in trunk/libavcodec: cabac.h h264.c
Author: michael Date: Thu Oct 19 03:19:03 2006 New Revision: 6732 Modified: trunk/libavcodec/cabac.h trunk/libavcodec/h264.c Log: optimize sign decoding code in decode_residual() x86 is 4% faster on P3 C sign stuff + x86 code for everything else is also faster then before (sorry forgot to test pure C) ... and if i replace the second occurance of the sign decoding in decode_residual by the asm too then everything gets slower iam starting to think that it might be best to write the whole function in asm, playing this avoid random deoptimizations game with gcc is not fun at all Modified: trunk/libavcodec/cabac.h ============================================================================== --- trunk/libavcodec/cabac.h (original) +++ trunk/libavcodec/cabac.h Thu Oct 19 03:19:03 2006 @@ -575,6 +575,36 @@ } static int get_cabac_bypass(CABACContext *c){ +#if 0 //not faster + int bit; + asm volatile( + "movl "RANGE "(%1), %%ebx \n\t" + "movl "LOW "(%1), %%eax \n\t" + "shl $17, %%ebx \n\t" + "add %%eax, %%eax \n\t" + "sub %%ebx, %%eax \n\t" + "cdq \n\t" + "and %%edx, %%ebx \n\t" + "add %%ebx, %%eax \n\t" + "test %%ax, %%ax \n\t" + " jnz 1f \n\t" + "movl "BYTE "(%1), %%ebx \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%%ebx), %%ecx \n\t" + "bswap %%ecx \n\t" + "shrl $15, %%ecx \n\t" + "addl $2, %%ebx \n\t" + "addl %%ecx, %%eax \n\t" + "movl %%ebx, "BYTE "(%1) \n\t" + "1: \n\t" + "movl %%eax, "LOW "(%1) \n\t" + + :"=&d"(bit) + :"r"(c) + : "%eax", "%ebx", "%ecx", "memory" + ); + return bit+1; +#else int range; c->low += c->low; @@ -588,7 +618,58 @@ c->low -= range; return 1; } +#endif +} + + +static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ +#ifdef ARCH_X86 + int bit; + asm volatile( + "movl "RANGE "(%1), %%ebx \n\t" + "movl "LOW "(%1), %%eax \n\t" + "shl $17, %%ebx \n\t" + "add %%eax, %%eax \n\t" + "sub %%ebx, %%eax \n\t" + "cdq \n\t" + "and %%edx, %%ebx \n\t" + "add %%ebx, %%eax \n\t" + "xor %%edx, %%ecx \n\t" + "sub %%edx, %%ecx \n\t" + "test %%ax, %%ax \n\t" + " jnz 1f \n\t" + "movl "BYTE "(%1), %%ebx \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%%ebx), %%edx \n\t" + "bswap %%edx \n\t" + "shrl $15, %%edx \n\t" + "addl $2, %%ebx \n\t" + "addl %%edx, %%eax \n\t" + "movl %%ebx, "BYTE "(%1) \n\t" + "1: \n\t" + "movl %%eax, "LOW "(%1) \n\t" + + :"+c"(val) + :"r"(c) + : "%eax", "%ebx", "%edx", "memory" + ); + return val; +#else + int range, mask; + c->low += c->low; + + if(!(c->low & CABAC_MASK)) + refill(c); + + range= c->range<<17; + c->low -= range; + mask= c->low >> 31; + range &= mask; + c->low += range; + return (val^mask)-mask; +#endif } + //FIXME the x86 code from this file should be moved into i386/h264 or cabac something.c/h (note ill kill you if you move my code away from under my fingers before iam finished with it!) //FIXME use some macros to avoid duplicatin get_cabac (cant be done yet as that would make optimization work hard) #ifdef ARCH_X86 Modified: trunk/libavcodec/h264.c ============================================================================== --- trunk/libavcodec/h264.c (original) +++ trunk/libavcodec/h264.c Thu Oct 19 03:19:03 2006 @@ -6168,11 +6168,9 @@ if( get_cabac( CC, ctx ) == 0 ) { if( !qmul ) { - if( get_cabac_bypass( CC ) ) block[j] = -1; - else block[j] = 1; + block[j] = get_cabac_bypass_sign( CC, -1); }else{ - if( get_cabac_bypass( CC ) ) block[j] = (-qmul[j] + 32) >> 6; - else block[j] = ( qmul[j] + 32) >> 6; + block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6;; } abslevel1++;
On Thu, Oct 19, 2006 at 03:19:04AM +0200, michael wrote:
Modified: trunk/libavcodec/cabac.h ============================================================================== --- trunk/libavcodec/cabac.h (original) +++ trunk/libavcodec/cabac.h Thu Oct 19 03:19:03 2006 @@ -575,6 +575,36 @@ } [...] + +static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ +#ifdef ARCH_X86 + int bit; + asm volatile( [...] + "movl %%eax, "LOW "(%1) \n\t" + + :"+c"(val) + :"r"(c) + : "%eax", "%ebx", "%edx", "memory"
Don't know how this broken code survived so long but there's no way it could possibly work when compiling with PIC. I just got a report on #ffmpeg from a user running into trouble here... Rich
Hi On Mon, Nov 27, 2006 at 02:33:33AM -0500, Rich Felker wrote:
On Thu, Oct 19, 2006 at 03:19:04AM +0200, michael wrote:
Modified: trunk/libavcodec/cabac.h ============================================================================== --- trunk/libavcodec/cabac.h (original) +++ trunk/libavcodec/cabac.h Thu Oct 19 03:19:03 2006 @@ -575,6 +575,36 @@ } [...] + +static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ +#ifdef ARCH_X86 + int bit; + asm volatile( [...] + "movl %%eax, "LOW "(%1) \n\t" + + :"+c"(val) + :"r"(c) + : "%eax", "%ebx", "%edx", "memory"
Don't know how this broken code survived so long
maybe noone uses PIC lavc ...
but there's no way it could possibly work when compiling with PIC.
push ebx asm pop ebx anyone wants to send a bugreport to the gcc devels ;) its funny, its a obvious bug, gcc can save and restore ebx, its not different from any other used register unless of course gcc is missdesigned and handles ebx in some special way but still i know its hopeless to report ... [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB In the past you could go to a library and read, borrow or copy any book Today you'd get arrested for mere telling someone where the library is
On Monday, 27 November 2006 at 11:56, Michael Niedermayer wrote:
Hi
On Mon, Nov 27, 2006 at 02:33:33AM -0500, Rich Felker wrote:
On Thu, Oct 19, 2006 at 03:19:04AM +0200, michael wrote:
Modified: trunk/libavcodec/cabac.h ============================================================================== --- trunk/libavcodec/cabac.h (original) +++ trunk/libavcodec/cabac.h Thu Oct 19 03:19:03 2006 @@ -575,6 +575,36 @@ } [...] + +static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ +#ifdef ARCH_X86 + int bit; + asm volatile( [...] + "movl %%eax, "LOW "(%1) \n\t" + + :"+c"(val) + :"r"(c) + : "%eax", "%ebx", "%edx", "memory"
Don't know how this broken code survived so long
maybe noone uses PIC lavc ...
Believe me, people do use it. Regards, R. -- MPlayer developer and RPMs maintainer: http://rpm.greysector.net/mplayer/ There should be a science of discontent. People need hard times and oppression to develop psychic muscles. -- from "Collected Sayings of Muad'Dib" by the Princess Irulan
On Mon, Nov 27, 2006 at 12:08:40PM +0100, Dominik 'Rathann' Mierzejewski wrote:
+static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ +#ifdef ARCH_X86 + int bit; + asm volatile( [...] + "movl %%eax, "LOW "(%1) \n\t" + + :"+c"(val) + :"r"(c) + : "%eax", "%ebx", "%edx", "memory"
Don't know how this broken code survived so long
maybe noone uses PIC lavc ...
Believe me, people do use it.
I'll remember to cite this thread next time uau flames about gcc 2.95 support, saying it doesn't matter because the c++ declarations lasted for a few months with nobody noticing. :)) Apparently his precious PIC support is just as unnecessary. :) Rich
On Mon, 2006-11-27 at 16:04 -0500, Rich Felker wrote:
On Mon, Nov 27, 2006 at 12:08:40PM +0100, Dominik 'Rathann' Mierzejewski wrote:
maybe noone uses PIC lavc ...
Believe me, people do use it.
I'll remember to cite this thread next time uau flames about gcc 2.95 support, saying it doesn't matter because the c++ declarations lasted for a few months with nobody noticing. :)) Apparently his precious PIC support is just as unnecessary. :)
"his precious" PIC support? That sounds like I would have promoted ffmpeg PIC support as being particularly important, which I have not done. Is there any case where PIC with that asm could be compiled except enabling shared libraries on AMD64 or manually forcing -pic on x86-32 (in which case reporting errors would be less likely)? There certainly have been reports of problems with asm on AMD64 on #ffmpeg at least, though I haven't paid much attention to the details. Even if no one would have noticed PIC breakage (which does not actually seem to be true) for as long as MPlayer not supporting gcc 2.95 was unnoticed that alone of course wouldn't make PIC support "just as unnecessary". There are other reasons why support for gcc 2.95 should be dropped; that it already was unsupported for months without serious problems just demonstrates that dropping support is a practical choice.
participants (5)
-
dalias@aerifal.cx -
dominik@rangers.eu.org -
michaelni@gmx.at -
subversion@mplayerhq.hu -
uoti.urpala@pp1.inet.fi