public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Marko Ristola <marko.ristola@kolumbus.fi>
To: Marko Ristola <marko.ristola@kolumbus.fi>
Cc: Linux Media Mailing List <linux-media@vger.kernel.org>
Subject: Re: [PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function
Date: Sun, 27 Jun 2010 12:09:56 +0300	[thread overview]
Message-ID: <4C271564.2020501@kolumbus.fi> (raw)
In-Reply-To: <4C2615FB.2000805@kolumbus.fi>


Hi

Here is an improved version of the original patch:
The original patch removed unnecessary copying for 204 sized packets only.
This patch improves performance for 188 sized packets too.

Unnecessary copying means: if dvb_dmx_swfilter(_204)() doesn't have to
modify
the source packet, the source packet is delivered for
dvb_dmx_swfilter_packet()
without copying.

This assumes, that a DMA transfer won't modify the accepted 188/204 sized
packet underneath while dvb_dmx_swfilter_packet() processes it.
The assumption is already in dvb_dmx_swfilter_packets().

With tasklets the risk for breaking the assumption is low. If there
would be
a normal thread instead of a tasklet, copying from the DMA buffer might
come too late.

Could someone test this patch who uses the dvb_dmx_swfilter() function
(188 sized)?

So _dvb_dmx_swfilter is now common for both 188 and 204 sized packet
parsing.
The measure was done during recording of H.264 steram under VDR,
using "perf top -d 10"

   PerfTop:      62 irqs/sec  kernel:80.6% [1000Hz cycles],  (all, 1 CPUs)

             samples  pcnt
function                                            DSO

              339.00 18.1%
dvb_dmx_swfilter_packet                            
[dvb_core]                                                   
              315.00 16.9%
acpi_pm_read                                       
[kernel.kallsyms]                                            
               70.00  3.7%
_ZN2SI5CRC325crc32EPKcij                           
/usr/sbin/vdr                                                
               53.00  2.8%
mantis_i2c_xfer                                    
[mantis_core]                                                
               53.00  2.8%
__mktime_internal                                  
/lib64/libc-2.12.so                                          
               39.00  2.1%
_ZN14cAudioRepacker6RepackEP17cRingBufferLinearPKhi
/usr/sbin/vdr                                                
               33.00  1.8%
delay_tsc                                          
[kernel.kallsyms]                                            
               30.00  1.6%
dvb_dmx_memcopy                                    
[dvb_core]                                                   
               28.00  1.5%
dvb_ringbuffer_write                               
[dvb_core]                                                   
               28.00  1.5%
_dvb_dmx_swfilter                                  
[dvb_core]                                                   


diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c
b/drivers/media/dvb/dvb-core/dvb_demux.c
index 977ddba..2ddaaaa 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,95 +478,78 @@ void dvb_dmx_swfilter_packets(struct dvb_demux
*demux, const u8 *buf,
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
-void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+static inline int findNextSyncByte(const u8 *buf, int pos, size_t
count, const int pktsize)
+{
+    while(likely(pos < count)) {
+        if (likely(buf[pos] == 0x47 || (pktsize == 204 && buf[pos] ==
0xB8)))
+            break;
+        pos++;
+    }
+
+    return pos;
+}
+
+/* pktsize must be either 204 or 188. If pktsize is 204, 0xB8 must be
accepted for SYNC byte too, but then convert it into 0x47.
+ * Designed pktsize so, that compiler would remove 204 related code
during inlining. */
+static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8
*buf, size_t count, const int pktsize)
 {
     int p = 0, i, j;
+    const u8 *q;
 
     spin_lock(&demux->lock);
 
-    if (demux->tsbufp) {
+    if (likely(demux->tsbufp)) { /* tsbuf[0] is now 0x47. */
         i = demux->tsbufp;
-        j = 188 - i;
-        if (count < j) {
+        j = pktsize - i;
+        if (unlikely(count < j)) {
             memcpy(&demux->tsbuf[i], buf, count);
             demux->tsbufp += count;
             goto bailout;
         }
         memcpy(&demux->tsbuf[i], buf, j);
-        if (demux->tsbuf[0] == 0x47)
+        if (likely(demux->tsbuf[0] == 0x47)) /* double check */
             dvb_dmx_swfilter_packet(demux, demux->tsbuf);
         demux->tsbufp = 0;
         p += j;
     }
 
-    while (p < count) {
-        if (buf[p] == 0x47) {
-            if (count - p >= 188) {
-                dvb_dmx_swfilter_packet(demux, &buf[p]);
-                p += 188;
-            } else {
-                i = count - p;
-                memcpy(demux->tsbuf, &buf[p], i);
-                demux->tsbufp = i;
-                goto bailout;
-            }
-        } else
-            p++;
+    while (likely((p = findNextSyncByte(buf, p, count, pktsize)) <
count)) {
+        if (unlikely(count - p < pktsize))
+            break;
+
+        q = &buf[p];
+
+        if (unlikely(pktsize == 204 && (*q == 0xB8))) {
+            memcpy(demux->tsbuf, q, 188);
+            demux->tsbuf[0] = 0x47;
+            q = demux->tsbuf;
+        }
+        dvb_dmx_swfilter_packet(demux, q);
+        p += pktsize;
+    }
+
+    i = count - p;
+    if (likely(i)) {
+        memcpy(demux->tsbuf, &buf[p], i);
+        demux->tsbufp = i;
+        if (unlikely(pktsize == 204 && demux->tsbuf[0] == 0xB8))
+            demux->tsbuf[0] = 0x47;
     }
 
 bailout:
     spin_unlock(&demux->lock);
 }
 
+void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+{
+    _dvb_dmx_swfilter(demux, buf, count, 188);
+}
+
 EXPORT_SYMBOL(dvb_dmx_swfilter);
 
 void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
size_t count)
 {
-    int p = 0, i, j;
-    u8 tmppack[188];
-
-    spin_lock(&demux->lock);
-
-    if (demux->tsbufp) {
-        i = demux->tsbufp;
-        j = 204 - i;
-        if (count < j) {
-            memcpy(&demux->tsbuf[i], buf, count);
-            demux->tsbufp += count;
-            goto bailout;
-        }
-        memcpy(&demux->tsbuf[i], buf, j);
-        if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) {
-            memcpy(tmppack, demux->tsbuf, 188);
-            if (tmppack[0] == 0xB8)
-                tmppack[0] = 0x47;
-            dvb_dmx_swfilter_packet(demux, tmppack);
-        }
-        demux->tsbufp = 0;
-        p += j;
-    }
-
-    while (p < count) {
-        if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
-            if (count - p >= 204) {
-                memcpy(tmppack, &buf[p], 188);
-                if (tmppack[0] == 0xB8)
-                    tmppack[0] = 0x47;
-                dvb_dmx_swfilter_packet(demux, tmppack);
-                p += 204;
-            } else {
-                i = count - p;
-                memcpy(demux->tsbuf, &buf[p], i);
-                demux->tsbufp = i;
-                goto bailout;
-            }
-        } else {
-            p++;
-        }
-    }
-
-bailout:
-    spin_unlock(&demux->lock);
+    _dvb_dmx_swfilter(demux, buf, count, 204);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_204);


  reply	other threads:[~2010-06-27  9:10 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-26 15:00 [PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function Marko Ristola
2010-06-27  9:09 ` Marko Ristola [this message]
2010-06-27 19:30   ` Marko Ristola
  -- strict thread matches above, loose matches on Subject: below --
2010-08-07  9:47 Marko Ristola
2010-08-07 11:22 ` Marko Ristola

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C271564.2020501@kolumbus.fi \
    --to=marko.ristola@kolumbus.fi \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox