0

I am trying to read a struct from a binary byte buffer using cast and pack. I was trying to keep track of worst case read time from in memory buffer so I decided to keep a chrono high resolution clock nano timer. Whenever the timer increased I printed the value. It gave me a worst case scenario of about 20 micro seconds which was huge considering the size of the struct. When I measured the average time taken it came out to be ~20 nanoseconds. Then I measured how many times was I breaching 50. And it turns out of the ~20 million times, I was breaching 50 nanoseconds only 500 times.

My question is what can possibly cause this performance fluctuation: average of 20 and worst of 20,000?

Secondly, how can I ensure a constant time performance. I am compiling with -O3 and C++11.

 // new approach
 #pragma pack(push, 1)
 typedef struct {
    char a;
    long b, c;
    char d, name[10];
    int e , f;
    char g, h;
    int h, i;
} myStruct;
#pragma pack(pop)


//in function where i am using it


 auto am1 = chrono::high_resolution_clock::now();
 myStruct* tmp = (myStruct*)cTemp;
 tmp->name[10] = 0;
 auto am2 = chrono::high_resolution_clock::now();
 chrono::duration<long, nano> arM = chrono::duration_cast<chrono::nanoseconds>(am2 - am1);
 if(arM.count() > maxMPO.count())
 {
     cout << "myStruct read time increased: "  << arM.count() <<     "\n";
 maxMPO = arM;
 }

I am using g++4.8 with C++11 and an ubuntu server.

15
  • You need to measure the impact of external factors. Commented Sep 26, 2014 at 13:41
  • @Bartek, what external factors? any suggestions on how to go about it? Commented Sep 26, 2014 at 13:43
  • Yep, you might try using a proper benchmarking library that will repeat the tests automatically and report that information. Commented Sep 26, 2014 at 13:43
  • 1
    @Naveen: You mean tmp->name[9] = 0 (9 is the last valid index of an array of size 10). I think that given your use case the average time is more important than the maximum 'spike' time? Commented Sep 26, 2014 at 14:47
  • 1
    @Naveen: You still can't put a null byte at name[10], that's undefined behaviour and is almost certainly overwriting the low (or high if big endian) byte of e. You'll need to copy the bytes out into a larger buffer and put the null character there (obviously, only do this at the last minute when you need to actually print them out using c-strings -- otherwise, just keep them non-null terminated). Commented Sep 26, 2014 at 15:17

1 Answer 1

1

what can possibly cause this performance fluctuation: avg of 20 and worst of 20,000?

On a PC (or Mac, or any desktop), there are Ethernet interrupts, timers, mem-refresh, and dozens of other things going on over which you have no (or very little) control.

You might consider changing the target. If you use a single board computer (SBC) with only static ram, and a network connection which you can turn off and disconnect, and timers and clocks and every other kind of interrupt under your software control, you might achieve an acceptable result.

I once worked with a gal who wrote software for an 8085 SBC. When we hooked up a scope and saw the waveform stability of a software controlled bit, I thought she must have added logic chips. It was amazing.

You simply can not achieve 'jitter' free behaviour on a desktop.

Sign up to request clarification or add additional context in comments.

1 Comment

It's not a desktop. It's an intel xeon ubuntu 14.04 server. But I guess ehternet jitters etc. would apply to it as well.

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.