Main Site Documentation

EMX and RLP


#1

I have RLP running. I started with a small test. I am moving information from a structure to a byte array. This was my original code:

Utility.InsertValueIntoArray(msg, 0, 2, ChannelID);
Utility.InsertValueIntoArray(msg, 2, 2, FrameID);
Utility.InsertValueIntoArray(msg, 4, 4, TxRxFlags);
Utility.InsertValueIntoArray(msg, 8, 4, TimeStamp);
Utility.InsertValueIntoArray(msg, 12 , 2, ExtraDataIndex);
Utility.InsertValueIntoArray(msg, 14 , 2, DataSize);

and it became this:

Program.AddHeader.InvokeEx(gp, m_pMsg);

Where gp is an array of 6 uint’s and m_pMsg is my byte array. Thought this might be a good test if not the best use of this technology. I was surprised to find that the invoke basically takes 3 times as long as the six utility calls. The utility calls average .885 ms to execute. The invoke call averages 2.443 ms. Is this what you would expect?


#2

We explained this on phone, RLP calls are to replace large windows of processor intensive task, like image decoding or CRC…in your case, change the format of large data blocks


#3

I know what you said on the phone. You did not indicate what the overhead would cost. My routine does nothing more than six assignments, so the entire time is the overhead of the call. Obviously you are not surprised by the numbers. Since this is not that case with other assemblies, the question is this - why so expensive?


#4

To know the time needed exactly, please make an empty project with no other threads than main.
Empty the C++ function (do nothing in it).
Do this:


// Get RLP functions first...

DateTime start = DateTime.Now;
InvokeEx(uint32Array, uint8Array);
DateTime end= DateTime.Now;

Debug.Print((end-start).ToString());

What is the result?

To answer your question, there are many things involved like getting the parameters together, checking the types, checking for errors and invoking native code, then getting back to C# and checking exceptions… There might be a room for optimization. We can look into it. But after getting to C++ code, you should get a lot of speed increase. So if you can do things in batches in c++, it will be a lot faster.


#5

Consider it as a “shipping overhead”.


#6

Yeah…moving objects from C# to native is something not simply done. Actually, I have no idea how the super smart guys at GHI have made it happen! Good job guys :clap:


#7

Mike - This is the routine I timed:


int AddHeader(unsigned int *gA, void **args, unsigned int argsCount, unsigned int *argSize)
{
	unsigned char *pMsg = (unsigned char*)args[0];  // this is msg array

	*((unsigned short *)(&pMsg[0])) = (unsigned short)gA[0];
	*((unsigned short *)(&pMsg[2])) = (unsigned short)gA[1];
	*((unsigned int *)(&pMsg[4])) = gA[2];
	*((unsigned int *)(&pMsg[8])) = gA[3];
	*((unsigned short *)(&pMsg[12])) = (unsigned short)gA[4];
	*((unsigned short *)(&pMsg[14])) = (unsigned short)gA[5];

	return 1;
}

It is not completely empty but close enough for this. I have an accumulating timer that I have placed around this call. I generate 1000 events. The number I found is the average across those events. I can empty this out, but the difference cannot be enough to proceed with the current design. We need these calls to approximate a utility call.

We do not have any large blocks of code required to manage a single message. Time drains away in little drips and drabs until the message handling eats up 9ms. We are interested in doing this in 1-2. I have another strategy that will move processing out of .Net in a different manner. It was good to see RLP in action. We may yet have need for it.


#8

ok the C++ is fine, it is fast. You do not have to change it.
I still recommend trying the code above with your existing function to measure the overhead time. Maybe something else is increasing the delay…