1

I need to continuously fill an array of 16384 double elements from a device that is delivering an array of data that is 332 elements in length (these have a data type of short). Currently copying takes 28ms to fill the 16384 element array. I would like to get this under 10ms at least. In the following code the method getData returns two short arrays of 332 elements(iBuf and qBuf). This method takes 14 ticks (3uS) so is not relevant for speed.

        getData();

        while (keepGoing)
        {
            for (int i = 0; i < 16384; i++)
            {
                iData[i] = ibuf[rawCounter];
                qData[i] = qbuf[rawCounter];

                rawCounter++;

                if (rawCounter == samplesPerPacket)
                {
                    getData();
                    rawCounter = 0;
                }  

                //processing of data occurs here
            } 

Thanks for any help and suggestions

3
  • 2
    msdn.microsoft.com/en-us/library/system.buffer.blockcopy Commented May 22, 2016 at 3:26
  • this is a really small optimization, but have you tried moving the declaration of int out of the for loop? no point in declaring it for every while iteration Commented May 23, 2016 at 17:42
  • why are you making duplicates? Commented May 23, 2016 at 17:44

3 Answers 3

2

Using the Array.copy method might help you

while(keeping)
{
Array.Copy(ibuf,0,iData,counter,iData.Length)
counter += iData.Length

//Exit while once you hit 16384
//Might also need to check you don't overflow buffer since 16384 doesn't divide evenly into 332.
} 
Sign up to request clarification or add additional context in comments.

3 Comments

Array copy IIRC is heavily optimized by the JIT (using SMD for larger blocks). Good hint.
The main issue here seems to be the checks to avoid the buffer overflows. Once those are in place, the execution time goes up to 58 ms.
What were you doing to check? are you just checking the counter?
0

First off your code will not compile as is. Try to edit to make a minimum example of what you want done. You are missing initialization (new statements) and it appears like you are writing Java code in C#.

At a minimum use Array.Copy(). Alternatively you can use pointers (if buffers contain intrinsic values) or as mentioned before BlockCopy() which copies bytes. Use the sizeof() function to find how many bytes per element.

1 Comment

Thanks. I tried array.copy but adding the checks for the buffer overflow bring execution time up to 58ms.
0

You can use the following technique where we took advantage of the fact that the processor is 32-bit ( 4 Bytes ), on 64-bit processor you just need to replace 4 by 8 in the method.

public static unsafe void CopyUnsafe(byte[] sourceArray, int sourceIndex, byte[] destinationArray, int destinationIndex, int length)
{
    const int procInstrSize = 4; 
    fixed (byte* pDst = &destinationArray[destinationIndex])
    {
        fixed (byte* source = &sourceArray[sourceIndex])
        {
            byte* ps = source;
            byte* pd = pDst;
            // Loop over the count in blocks of 4 bytes, copying an integer (4 bytes) at a time:
            for (int i = 0; i < length / procInstrSize; i++)
            {
                *((int*) pd) = *((int*) ps);
                pd += procInstrSize;
                ps += procInstrSize;
            }

            // Complete the copy by moving any bytes that weren't moved in blocks of 4:
            for (int i = 0; i < length % procInstrSize; i++)
            {
                *pd = *ps;
                pd++;
                ps++;
            }
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.