Main Site Documentation

How can I improve execution time w/o RLP?


#1

Hi everybody,

Ive got a problem with execution time and I was wondering if anyone had any ideas on how I might go about speeding up the following code. Ive tried to avoid any extra math or variable creation in the loop, but beyond that Im not sure where to go. This is running on an original FEZ Panda. Any advice would be appreciated.

Thanks,
Doug

public class Program
    {
        
        public static void Main()
        {
            //Setup Lights
            GELightController c = new GELightController(SPI.SPI_module.SPI2, 25);
            byte[] address = new byte[25] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
            c.BigBufferEnabled = true;
            c.SetupBigBuffer();
            c.Initialize(address);

            //Setup Network
            byte[] ip = { 192, 168, 40, 85 };
            byte[] subnet = { 255, 255, 255, 0 };
            byte[] gateway = { 192, 168, 40, 1 };
            byte[] mac = { 0x00, 0x26, 0x1C, 0x7B, 0x29, 0xE8 };
            WIZnet_W5100.Enable(SPI.SPI_module.SPI1, (Cpu.Pin)FEZ_Pin.Digital.Di10, (Cpu.Pin)FEZ_Pin.Digital.Di7, true);
            NetworkInterface.EnableStaticIP(ip, subnet, gateway, mac);
            NetworkInterface.EnableStaticDns(new byte[] { 192, 168, 40, 1 });
            Socket serversocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 2000);
            serversocket.Bind(remoteEndPoint);

            byte[] inBuf = new byte[100];
            int count;

            //Wait for a new packet and process when it arrives.
            while (true)
            {
                if (serversocket.Poll(-1, SelectMode.SelectRead))
                {
                    count = serversocket.ReceiveFrom(inBuf, ref remoteEndPoint);

                    c.SetBigBuffer(inBuf[0], 0xcc, inBuf[1], inBuf[2], inBuf[3]); //0
                    c.SetBigBuffer(inBuf[4], 0xcc, inBuf[5], inBuf[6], inBuf[7]); //1
                    c.SetBigBuffer(inBuf[8], 0xcc, inBuf[9], inBuf[10], inBuf[11]); //2
                    c.SetBigBuffer(inBuf[12], 0xcc, inBuf[13], inBuf[14], inBuf[15]); //3
                    c.SetBigBuffer(inBuf[16], 0xcc, inBuf[17], inBuf[18], inBuf[19]); //4
                    c.SetBigBuffer(inBuf[20], 0xcc, inBuf[21], inBuf[22], inBuf[23]); //5
                    c.SetBigBuffer(inBuf[24], 0xcc, inBuf[25], inBuf[26], inBuf[27]); //6
                    c.SetBigBuffer(inBuf[28], 0xcc, inBuf[29], inBuf[30], inBuf[31]); //7
                    c.SetBigBuffer(inBuf[32], 0xcc, inBuf[33], inBuf[34], inBuf[35]); //8
                    c.SetBigBuffer(inBuf[36], 0xcc, inBuf[37], inBuf[38], inBuf[39]); //9
                    c.SetBigBuffer(inBuf[40], 0xcc, inBuf[41], inBuf[42], inBuf[43]); //10
                    c.SetBigBuffer(inBuf[44], 0xcc, inBuf[45], inBuf[46], inBuf[47]); //11
                    c.SetBigBuffer(inBuf[48], 0xcc, inBuf[49], inBuf[50], inBuf[51]); //12
                    c.SetBigBuffer(inBuf[52], 0xcc, inBuf[53], inBuf[54], inBuf[55]); //13
                    c.SetBigBuffer(inBuf[56], 0xcc, inBuf[57], inBuf[58], inBuf[59]); //14
                    c.SetBigBuffer(inBuf[60], 0xcc, inBuf[61], inBuf[62], inBuf[63]); //15
                    c.SetBigBuffer(inBuf[64], 0xcc, inBuf[65], inBuf[66], inBuf[67]); //16
                    c.SetBigBuffer(inBuf[68], 0xcc, inBuf[69], inBuf[70], inBuf[71]); //17
                    c.SetBigBuffer(inBuf[72], 0xcc, inBuf[73], inBuf[74], inBuf[75]); //18
                    c.SetBigBuffer(inBuf[76], 0xcc, inBuf[77], inBuf[78], inBuf[79]); //19
                    c.SetBigBuffer(inBuf[80], 0xcc, inBuf[81], inBuf[82], inBuf[83]); //20
                    c.SetBigBuffer(inBuf[84], 0xcc, inBuf[85], inBuf[86], inBuf[87]); //21
                    c.SetBigBuffer(inBuf[88], 0xcc, inBuf[89], inBuf[90], inBuf[91]); //22
                    c.SetBigBuffer(inBuf[92], 0xcc, inBuf[93], inBuf[94], inBuf[95]); //23
                    c.SetBigBuffer(inBuf[96], 0xcc, inBuf[97], inBuf[98], inBuf[99]); //24
                
                    c.FlushBigBuffer();  //Flush the buffer and control the lights.
                    Debug.GC(true);
                } 
            
            }
        }
    }

#2

You say you have a problem with execution speed, but provide no quantitative information. How can we judge if your expectations are realistic?

All of the calls in your loop are to an object of class GELightController but you did not include this code. Is this your code?


#3

You are correct Mike, I did not provide any quantitative information as I am not trying to determine whether my expectations are realistic just yet. I dont really have any at the moment; my goal is to speed up what I have and see how it looks. That being said, the ultimate application of this will be a music visualization system, with the visualizations generated on a computer and the light data multicast to the Panda. If Im only attempting to process a 4 byte udp packet (or several 4 byte packets) and sending an update to only one or a few bulbs, there is no perceivable delay between when the light(s) should update and when they actually do.

The GELightController code is not mine, it is a driver that I am using from the code library.
http://code.tinyclr.com/project/196/ge-35-christmas-lights-individually-addressable/


#4

I would suggest that your first step would be to figure out where your latency is coming from. If you control the lights without the network (do the calls to SetBigBuffer() and FlushBigBuffer() without the network code) and see whether it’s “fast enough”. Once you’ve done that, you can move on to other things.

I can tell you that unless the calls to Debug.GC() are going to introduce some latency. If it were my code, I would consider it a bug if they were required.

As for the network code, there are a lot of variables involved. A giant one is the W5100. I haven’t any idea how many packets per second it’s capable of processing.


#5

You are calling Setbigbuffer a lot with a bunch of parameters each time. NETMF introduces several hundred microseconds per method call.

Can you not pass a reference to the array and work with the bytes in a big block? Also try built-in array manipulation methods like Array.Copy.

What about using a stream to fish out the data you need and only call into a method when you have something to process.

Try to keep your repetitive processing in one method.