Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Addressing 8 Channel A to D Data

Reply
Thread Tools

Addressing 8 Channel A to D Data

 
 
Artist
Guest
Posts: n/a
 
      08-18-2012
In an ADSP-BF547 I will have a buffer of data from an AD7606 A to D Converter. There will be 200k samples from each of eight channels for a total of 1..6M samples. On this data I need to do one DFT for each channel in real time. It is essential the DFT be as efficient as possible and so arises the question about the most efficient way to address the data in a channel.

For this many samples in a channel I do not have a choice about the sequence the DMA will put the data in the memory. The sequence is defined by the below equation which maps a sample row and a channel number to an index in the dynamically allocated linear array that data is stored in:

i = s*8 + c eq 1

Where:
i is the index number of an A to D data element in the linear array
s is the sample row number, 0 <= s < 200e3
c is the A to D channel number (column). There are eight of them. 0 <= c< 8

I could use the above equation 1 which would require one multiplication andone addition.

Since the number of channels is a convenient power of two I could instead shift and OR:

i = s<<3 | c eq 2

I could also dynamically allocate a linear array of pointers to each row:

u16 ** D2 = (u16 **)malloc( 200e3 * sizeof( u16 ** ) );
for( j=0; j<200e3; j++ ){
D2[j] = &D[ J*8 ];
}

Where:
D is the array DMA stored the A to D data in.
D2 is an array of pointers.

This way the data in D can be accessed by

Dadc = D2[s][c] eq 3

I expect the above for loop to be executed only once per buffer at initialization because the DMA alternates between two buffers. While it is filling one, the DFT will be done on the other. A DFT for a buffer has to be completed before DMA has finished filling the other buffer.

I need to know which of the above equations, 1, 2, or 3, will access the data quickest.
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      08-18-2012
On 2012-08-18, Artist <(E-Mail Removed)> wrote:
> I could also dynamically allocate a linear array of pointers to each row:
>
> u16 ** D2 = (u16 **)malloc( 200e3 * sizeof( u16 ** ) );


That should probably be sizeof(u16*).
You can avoid this mistake by using the idiom

u16 ** D2 = malloc(200e3 * sizeof *D2);

> I need to know which of the above equations, 1, 2, or 3, will access
> the data quickest.


Try them all, and measure.
 
Reply With Quote
 
 
 
 
Willem
Guest
Posts: n/a
 
      08-18-2012
Artist wrote:
) In an ADSP-BF547 I will have a buffer of data from an AD7606 A to D
) Converter. There will be 200k samples from each of eight channels for a
) total of 1.6M samples. On this data I need to do one DFT for each channel
) in real time. It is essential the DFT be as efficient as possible and so
) arises the question about the most efficient way to address the data in a
) channel.
)
) For this many samples in a channel I do not have a choice about the
) sequence the DMA will put the data in the memory. The sequence is defined
) by the below equation which maps a sample row and a channel number to an
) index in the dynamically allocated linear array that data is stored in:
)
) i = s*8 + c eq 1
)
) Where:
) i is the index number of an A to D data element in the linear array
) s is the sample row number, 0 <= s < 200e3
) c is the A to D channel number (column). There are eight of them. 0 <= c < 8
)
) I could use the above equation 1 which would require one multiplication and one addition.
)
) Since the number of channels is a convenient power of two I could instead shift and OR:
)
) i = s<<3 | c eq 2

Any halfway decent compiler will optimize s*8 to s<<3 anyway, or will
optimize both to some different kind of operation. So effectively they're
likely to give the exact same result.

) I could also dynamically allocate a linear array of pointers to each row:
)
) u16 ** D2 = (u16 **)malloc( 200e3 * sizeof( u16 ** ) );
) for( j=0; j<200e3; j++ ){
) D2[j] = &D[ J*8 ];
) }
)
) Where:
) D is the array DMA stored the A to D data in.
) D2 is an array of pointers.
)
) This way the data in D can be accessed by
)
) Dadc = D2[s][c] eq 3

That seems like it would be slower except on hardware where memory lookups
are cheaper than arithmetics (old 8-bit hardware, or PICs, for example).

) I expect the above for loop to be executed only once per buffer at
) initialization because the DMA alternates between two buffers. While it
) is filling one, the DFT will be done on the other. A DFT for a buffer has
) to be completed before DMA has finished filling the other buffer.
)
) I need to know which of the above equations, 1, 2, or 3, will access the data quickest.

If you *need* to know, then try all of them.

Also, you could maybe convert the pointer to something like: ((u16[8]) *)
I.E. a pointer to an array of 8 values. Then you can use double-indexing
on that and let the compiler figure out the arithmetics.

That will probably be equivalent to solutions 1 and 2, though.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-18-2012
Artist <(E-Mail Removed)> writes:
[...]
> u16 ** D2 = (u16 **)malloc( 200e3 * sizeof( u16 ** ) );
> for( j=0; j<200e3; j++ ){
> D2[j] = &D[ J*8 ];
> }

[...]

Ike Naar already pointed out that "sizeof (u16 **)" should be
"sizeof (u16*) -- or, better, "sizeof *D2". (u16** and u16* are
very likely to have the same size, but it's not guaranteed.)

But you should also be aware that 200e3 is a *floating-point* constant,
which means that it might be subject to rounding errors. You should
replace it with 200000 -- or, better, with a macro or constant with that
value.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      08-18-2012
Artist <(E-Mail Removed)> writes:
<snip>
> I need to know which of the above equations, 1, 2, or 3, will access
> the data quickest.


Since I think you'll have to try them all, you might want to consider
two other options:

4) Use a 2D array to get the compiler to do the address arithmetic.
It's unlikely, but the compiler might be able to do it better than
you can, but if it's no worse you get cleaner code and that can only
be a Good Thing.

5) Transpose the array, i.e. switch rows with columns. This alters the
access pattern and may be better or worse depending on things like
cache configuration and so on.

--
Ben.
 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      08-18-2012
Ben Bacarisse wrote:
) Artist <(E-Mail Removed)> writes:
)<snip>
)> I need to know which of the above equations, 1, 2, or 3, will access
)> the data quickest.
)
) Since I think you'll have to try them all, you might want to consider
) two other options:
)
) 4) Use a 2D array to get the compiler to do the address arithmetic.
) It's unlikely, but the compiler might be able to do it better than
) you can, but if it's no worse you get cleaner code and that can only
) be a Good Thing.

It's already a 2D array, isn't it?
You just need to cast it to the correct type.

) 5) Transpose the array, i.e. switch rows with columns. This alters the
) access pattern and may be better or worse depending on things like
) cache configuration and so on.

Nope. Quote from the OP:
)> For this many samples in a channel I do not have a choice about the
)> sequence the DMA will put the data in the memory.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
88888 Dihedral
Guest
Posts: n/a
 
      08-18-2012
Artist於 2012年8月18日星期*UTC+8上午11時47分59 寫道:
> In an ADSP-BF547 I will have a buffer of data from an AD7606 A to D Converter. There will be 200k samples from each of eight channels for a total of1.6M samples. On this data I need to do one DFT for each channel in real time. It is essential the DFT be as efficient as possible and so arises the question about the most efficient way to address the data in a channel.
>
>
>
> For this many samples in a channel I do not have a choice about the sequence the DMA will put the data in the memory. The sequence is defined by thebelow equation which maps a sample row and a channel number to an index inthe dynamically allocated linear array that data is stored in:
>
>
>
> i = s*8 + c eq 1
>
>
>
> Where:
>
> i is the index number of an A to D data element in the linear array
>
> s is the sample row number, 0 <= s < 200e3
>
> c is the A to D channel number (column). There are eight of them. 0 <=c < 8
>
>
>
> I could use the above equation 1 which would require one multiplication and one addition.
>
>
>
> Since the number of channels is a convenient power of two I could insteadshift and OR:
>
>
>
> i = s<<3 | c eq 2
>
>
>
> I could also dynamically allocate a linear array of pointers to each row:
>
>
>
> u16 ** D2 = (u16 **)malloc( 200e3 * sizeof( u16 ** ) );
>
> for( j=0; j<200e3; j++ ){
>
> D2[j] = &D[ J*8 ];
>
> }
>
>
>
> Where:
>
> D is the array DMA stored the A to D data in.
>
> D2 is an array of pointers.
>
>
>
> This way the data in D can be accessed by
>
>
>
> Dadc = D2[s][c] eq 3
>
>
>
> I expect the above for loop to be executed only once per buffer at initialization because the DMA alternates between two buffers. While it is filling one, the DFT will be done on the other. A DFT for a buffer has to be completed before DMA has finished filling the other buffer.
>
>
>
> I need to know which of the above equations, 1, 2, or 3, will access the data quickest.


OK, can you relax the precesion required?

Do you just need to track down the main carrier only ?

Do you really need an accurate spectrum analysis?

There are 4 cores in most mass production cspu on the streets nowadays,
and also ?00G routers are so cheap that one can put up 8 PCs in a lan for
the 8 DFTs.







 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      08-19-2012
Willem <(E-Mail Removed)> writes:

> Ben Bacarisse wrote:
> ) Artist <(E-Mail Removed)> writes:
> )<snip>
> )> I need to know which of the above equations, 1, 2, or 3, will access
> )> the data quickest.
> )
> ) Since I think you'll have to try them all, you might want to consider
> ) two other options:
> )
> ) 4) Use a 2D array to get the compiler to do the address arithmetic.
> ) It's unlikely, but the compiler might be able to do it better than
> ) you can, but if it's no worse you get cleaner code and that can only
> ) be a Good Thing.
>
> It's already a 2D array, isn't it?
> You just need to cast it to the correct type.


Yes, but the OP's 1, 2 and 3 were about the accesses, so I was adding a
fourth -- use 'native' [x][y] rather than treating the data as
1-dimensional (the OP's 1 and 2), or as an array of pointers (which is
how I interpreted their number 3).

<snip>
--
Ben.
 
Reply With Quote
 
Artist
Guest
Posts: n/a
 
      08-19-2012
On Saturday, August 18, 2012 9:13:56 AM UTC-7, 88888 Dihedral wrote:
> Artist於 2012年8月18日星期*UTC+8上午11時47分59 寫道:
>
> > In an ADSP-BF547 I will have a buffer of data from an AD7606 A to D Converter. There will be 200k samples from each of eight channels for a total of 1.6M samples. On this data I need to do one DFT for each channel in realtime. It is essential the DFT be as efficient as possible and so arises the question about the most efficient way to address the data in a channel.

>
> >

>
> >

>
> >

>
> > For this many samples in a channel I do not have a choice about the sequence the DMA will put the data in the memory. The sequence is defined by the below equation which maps a sample row and a channel number to an index in the dynamically allocated linear array that data is stored in:

>
> >

>
> >

>
> >

>
> > i = s*8 + c eq 1

>
> >

>
> >

>
> >

>
> > Where:

>
> >

>
> > i is the index number of an A to D data element in the linear array

>
> >

>
> > s is the sample row number, 0 <= s < 200e3

>
> >

>
> > c is the A to D channel number (column). There are eight of them. 0 <= c < 8

>
> >

>
> >

>
> >

>
> > I could use the above equation 1 which would require one multiplicationand one addition.

>
> >

>
> >

>
> >

>
> > Since the number of channels is a convenient power of two I could instead shift and OR:

>
> >

>
> >

>
> >

>
> > i = s<<3 | c eq 2

>
> >

>
> >

>
> >

>
> > I could also dynamically allocate a linear array of pointers to each row:

>
> >

>
> >

>
> >

>
> > u16 ** D2 = (u16 **)malloc( 200e3 * sizeof( u16 ** ) );

>
> >

>
> > for( j=0; j<200e3; j++ ){

>
> >

>
> > D2[j] = &D[ J*8 ];

>
> >

>
> > }

>
> >

>
> >

>
> >

>
> > Where:

>
> >

>
> > D is the array DMA stored the A to D data in.

>
> >

>
> > D2 is an array of pointers.

>
> >

>
> >

>
> >

>
> > This way the data in D can be accessed by

>
> >

>
> >

>
> >

>
> > Dadc = D2[s][c] eq 3

>
> >

>
> >

>
> >

>
> > I expect the above for loop to be executed only once per buffer at initialization because the DMA alternates between two buffers. While it is filling one, the DFT will be done on the other. A DFT for a buffer has to be completed before DMA has finished filling the other buffer.

>
> >

>
> >

>
> >

>
> > I need to know which of the above equations, 1, 2, or 3, will access the data quickest.

>
>
>
> OK, can you relax the precesion required?
>
>
>
> Do you just need to track down the main carrier only ?
>
>
>
> Do you really need an accurate spectrum analysis?
>
>
>
> There are 4 cores in most mass production cspu on the streets nowadays,
>
> and also ?00G routers are so cheap that one can put up 8 PCs in a lan for
>
> the 8 DFTs.


I need the main carrier only. It is a lock in amplifier. In normal operation DFT will output the amplitude of the main carrier's harmonic only, and none of the other harmonics. For cross talk rejection the each channel's harmonic will be different. For the DFT the sine wave multiplier will be factored out of the additions and subtractions as much as possible to minimize the floating point multiplications. This what an FFT does.

All eight channels has to be done by only one Blackfin ADSP-BF547. The choice of this processor was a compromise between computing power and power consumption. It has two 32 bit ALU's. It will be operated at clock speed of 525MHz.
 
Reply With Quote
 
Artist
Guest
Posts: n/a
 
      08-19-2012
On Saturday, August 18, 2012 1:13:13 AM UTC-7, Willem wrote:
>
> Also, you could maybe convert the pointer to something like: ((u16[8]) *)
>
> I.E. a pointer to an array of 8 values. Then you can use double-indexing
>
> on that and let the compiler figure out the arithmetics.
>
> That will probably be equivalent to solutions 1 and 2, though.
>


Casting to ((u16[8]) *) is what I will do. I was looking for a way to simply cast it like this earlier. What I had read about C and C++ is that both do 2 dimensional arrays by creating a linear array of pointers in the first dimension that point to an arrays of values as the second dimension. So I thought I would have to create an array of pointers as I did for eq 3.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Dual channel or triple channel? Zeke Computer Support 0 06-07-2010 03:40 PM
Re: Dual channel or triple channel? Tony Computer Support 0 06-06-2010 08:32 AM
Re: Dual channel or triple channel? VanguardLH Computer Support 1 06-06-2010 01:36 AM
Six channel or two channel sound on DVD? cydeweys@gmail.com DVD Video 1 10-10-2005 04:51 AM
Have two ATA100 Seagate drives in a vp6, one IDE channel comes up as mode 5 in winxp but the other channel is stuck in mode 4 Tim Computer Support 3 02-23-2004 03:35 AM



Advertisments