[asterisk-dev] Wanted: Missing CPU Cycles... Reward!

Steve Murphy murf at digium.com
Thu Nov 1 09:08:13 CDT 2007


On Wed, 2007-10-31 at 18:46 -0600, Steve Murphy wrote:
> On Wed, 2007-10-31 at 18:05 +0100, Vadim Lebedev wrote:
> > ...
> > Well the following is obviously MUUCH faster than the original:
> > 
> > static void pbx_substitute_variables(char *passdata, int datalen,
> > struct ast_channel *c, struct ast_exten *e)
> > {
> > 
> >         /* No variables or expressions in e->data, so why scan it?
> > */
> >         if (e->data && !strchr(e->data, '$'))
> >                 ast_copy_string(passdata, e->data, datalen);
> >                 return;
> >         }
> >         
> >         *passdata = 0;
> >         pbx_substitute_variables_helper(c, e->data, passdata,
> > datalen - 1);
> > }
> > 
> > 
> > Original:
> > static void pbx_substitute_variables(char *passdata, int datalen,
> > struct ast_channel *c, struct ast_exten *e)
> > {
> >         memset(passdata, 0, datalen);
> > 
> >         /* No variables or expressions in e->data, so why scan it?
> > */
> >         if (e->data && !strchr(e->data, '$') && !
> > strstr(e->data,"${") && !strstr(e->data,"$[") && !
> > strstr(e->data,"$(")) {
> >                 ast_copy_string(passdata, e->data, datalen);
> >                 return;
> >         }
> > 
> >         pbx_substitute_variables_helper(c, e->data, passdata,
> > datalen - 1);
> > }
> > 
> > 
> 
> Oh, and yes, I forgot to mention *passdata = 0; vs memset(passdata, 0,
> datalen);
> Considering that the passdata buffer is 8192 bytes long, just writing
> 1 byte vs. 8192 bytes WOULD be a huge savings in time. 
> 
> BUT, you can't do that. pbx_substitute_variables_helper will not work.
> It depends on passdata being nulled out, and it will fail to work
> correctly if you go that route.
> 
> murf

Hmmmm. I wrote another letter, that seems not to have made it, saying
that the part about not unnecessarily scanning the e->data is a good
idea, but my benchmark, there's always a ${} or $[] expression, or both,
so such an improvement won't help... and, that Tilghman has just added
that improvement to trunk... (a good idea is a good idea!)

But your *passdata = 0; idea got me to thinking. I determined to
re-write pbx_substitute_variables_helper_full() to eliminate the need to
zero out that 8K buffer 4 million times (for 4 million priorities to
execute). The further I studied how
pbx_substitute_variables_helper_full() was built, tho, the more I liked
it. So I gave up the idea of rewriting it, to just tweaking it to zero
out the byte after the last byte copied to the output buffer. That
turned out to be pretty simple. There are only 3 places in the routine
where bytes are copied.

That done, there were 2 places, where a 4K buffer was memset to zeroes,
for a recursive call. I got rid of these, also. Then, I went thru all
the source, and got rid of all the memsets (and array initializations)
in all the places it was done, to zero the buffer for
pbx_substitute_variables_helper/_full, and ran my perf measurements
again. Now, without having to zero out between 32 and 48 Gbytes of
buffer, it's now at 100K!!!

See http://svn.digium.com/svn/asterisk/team/murf/fast-ast3 for all this
work. If everybody would please review the mods, and test it, I'd
appreciate it. I'd like to merge this into trunk, as soon as possible,
if everyone is willing/no-one objects.

murf

-- 
Steve Murphy
Software Developer
Digium
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3227 bytes
Desc: not available
Url : http://lists.digium.com/pipermail/asterisk-dev/attachments/20071101/c4709e8c/attachment.bin 


More information about the asterisk-dev mailing list