Hello,
On 04.02.2011 17:31, Øyvind Harboe wrote:
On Fri, Feb 4, 2011 at 5:21 PM, Mathias K.<[email protected]> wrote:
this patch increase the speed of the buf_set_buf function around 30%.
how do you arrive at 30%?
There is no more slow math used in the iteration like "/" or "%". Only some more compare functions.
The array access is now changed to the faster pointer access and because that the index is no longer
needed.
What overall impact does this have?
If i dump 200000 words (24bit data) of the DSP563xx memory this function is called around 1401613
times and is the top time intensive function (gprof results). This patch would lower down the
function time.
I have append my test and the compile options are:
gcc -std=gnu99 -O2 main.c
The test use 0x2000000 iterations and the complete test with the new function is around 2 seconds
faster here:
buf_set_buf 0x02000000 iteration test:
runtime (seconds): old: 6.624271 new: 4.683590 diff: 1.940681
runtime (seconds): old: 6.681766 new: 4.617829 diff: 2.063937
runtime (seconds): old: 6.816424 new: 4.673407 diff: 2.143017
runtime (seconds): old: 6.986225 new: 4.701716 diff: 2.284509
runtime (seconds): old: 6.727926 new: 4.712746 diff: 2.015180
runtime (seconds): old: 6.756491 new: 4.673408 diff: 2.083083
runtime (seconds): old: 6.784063 new: 4.685366 diff: 2.098697
runtime (seconds): old: 6.805309 new: 4.750642 diff: 2.054667
I think in practice you can't feel it without high traffic on the jtag.
Regards,
Mathias
#include <stdio.h>
#include <stdint.h>
#include <sys/time.h>
/* optimized function */
void* buf_set_buf(const void *_src, unsigned src_start,
void *_dst, unsigned dst_start, unsigned len)
{
const uint8_t *src = _src;
uint8_t *dst = _dst;
unsigned sb,db,sq,dq;
sb = src_start / 8;
db = dst_start / 8;
sq = src_start % 8;
dq = dst_start % 8;
for (unsigned i = 0; i < len; i++)
{
if (((*src >> (sq&7)) & 1) == 1)
*dst |= 1 << (dq&7);
else
*dst &= ~(1 << (dq&7));
if ( sq++ == 7 )
{
sq = 0;
src++;
}
if ( dq++ == 7 )
{
dq = 0;
dst++;
}
}
return (uint8_t*)_dst;
}
/* old function */
void* buf_set_buf1(const void *_src, unsigned src_start,
void *_dst, unsigned dst_start, unsigned len)
{
const uint8_t *src = _src;
uint8_t *dst = _dst;
unsigned src_idx = src_start, dst_idx = dst_start;
for (unsigned i = 0; i < len; i++)
{
if (((src[src_idx / 8] >> (src_idx % 8)) & 1) == 1)
dst[dst_idx / 8] |= 1 << (dst_idx % 8);
else
dst[dst_idx / 8] &= ~(1 << (dst_idx % 8));
dst_idx++;
src_idx++;
}
return dst;
}
void dump( uint8_t * b, int l )
{
while(l--)
printf("%02X ",*b++);
printf("\n");
}
double time_diff( struct timeval * tv1, struct timeval * tv2 )
{
double f1,f2;
f1 = tv1->tv_usec;
f2 = tv2->tv_usec;
f1 = (tv1->tv_sec * 1.0) + (f1/1000000.0);
f2 = (tv2->tv_sec * 1.0) + (f2/1000000.0);
return f2-f1;
}
#define FITERATION 0x2000000
double test_new(void)
{
uint32_t i;
struct timeval tv1,tv2;
uint8_t src[200];
uint8_t dst[200];
for(i=0;i<200;i++)
{
src[i] = 0x80+i;
}
gettimeofday(&tv1,0);
for(i=0;i< FITERATION;i++)
buf_set_buf(src,0,dst,0,32);
gettimeofday(&tv2,0);
return time_diff(&tv1,&tv2);
// printf("%f\n",time_diff(&tv1,&tv2));
// dump(src,10);
// dump(dst,10);
}
double test_old(void)
{
uint32_t i;
struct timeval tv1,tv2;
uint8_t src[200];
uint8_t dst[200];
for(i=0;i<200;i++)
{
src[i] = 0x80+i;
}
gettimeofday(&tv1,0);
for(i=0;i< FITERATION;i++)
buf_set_buf1(src,0,dst,0,32);
gettimeofday(&tv2,0);
return time_diff(&tv1,&tv2);
// printf("%f\n",time_diff(&tv1,&tv2));
// dump(src,10);
// dump(dst,10);
}
int main()
{
double f1,f2;
printf("buf_set_buf 0x%08X iteration test:\n",FITERATION);
while(1)
{
f1 = test_new();
f2 = test_old();
printf("runtime (seconds): old: %f new: %f diff: %f\n",f2,f1,f2-f1);
}
return 0;
}
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development