🔒 Locked
QueryPerformanceCounter
Advertisement
Original Post
I have debuged it ~3 hours (note: i CAN'T trace it!) and i just don't get what is wrong. In one place in my code (which is error free [as far as i can tell about one line of code]) QueryPerformanceCounter returns always 0 - and everywhere else what it is supposed to return. Provided that hardware supports it (and it sure as hell does) - it should NEVER fail - or what? ??? Any ideas?
It says: "The operation completed successfully.".
Haa! Found the problem (i think).
QueryPerformanceCounter goes nuts when the address modulo with 4 is not 0 ! (Likely a limitation of the rdtsc instruction. Can anyone confirm?)
0041503D Bad
00415091 Bad
00415154 Good
004151A8 Good
004294B4 Good
(That is what i found out - besides of a little syntactical problem in assert i had)
Now, why the hell are they not aligned to 4 (as i have set it to in project options)!?
QueryPerformanceCounter goes nuts when the address modulo with 4 is not 0 ! (Likely a limitation of the rdtsc instruction. Can anyone confirm?)
0041503D Bad
00415091 Bad
00415154 Good
004151A8 Good
004294B4 Good
(That is what i found out - besides of a little syntactical problem in assert i had)
Now, why the hell are they not aligned to 4 (as i have set it to in project options)!?
Hm that's very odd, I don't know how likely that is. QueryPerformanceCounter accepts a LARGE_INTEGER which is just a 64-bit variable. Surely it doesn't matter if it's aligned or not? What are you passing in? Not that it should matter; it should just fill out that memory space that you pass in with the value.
cheers
sam
cheers
sam
Just a thought, but just maybe, the value is being overwritten by an array over0run or something. A variable you declared before the LARGE_INTEGER might be oversteppings its memory bounds and going over the data in the LARGE_INTEGER.
Just make sure you're checking 'li' right after you call QPC.
It's highly unlikely, but it *has* happened to me in the past so thought Id bring it up...
int overarray[];LARGE_INTEGER li;QueryPerformaceCounter( &li );// <-- doing something with overarray here.cout<< li.QuadPart<< endl;Just make sure you're checking 'li' right after you call QPC.
It's highly unlikely, but it *has* happened to me in the past so thought Id bring it up...
Argh. The damn board logouts me silently all the time! Auto login doesn't seem to work at all somewhy!?
Yeah, the last anonymous is me.
Yeah, the last anonymous is me.
Well it shouldn't re-order the elements in the struct. It will only align them, so it will (effectively) insert space into the struct. Were you passing that struct into QPC? Coz if so, then the struct that you pass in should probably look like the LARGE_INTEGER struct (i.e. it should be 64 bit - exactly - in size).
cheers
sam
cheers
sam
LARGE_INTEGER needs an 8 byte alignment - which I believe is the default for MS - I could be wrong. This is more of an issue in contrasting LARGE_INTEGER with FILETIME - that is, don't pass a LARGE_INTEGER as a FILETIME and vice versa. For more info: Windows Data Alignment on IPF, x86, and x86-64. That link even has a sample using QPF and QPC.
@izzo: "shouldn't re-order"
Aah... (mouth is singing and heart is worrying) c doesn't reorder anything - delphi/pascal does that. My bad.
Found out that by placing pack(1) pragma inside struct will do what i wanted - struct itself will be aligned to 4 and data in it to 1 (without inserting space to the end of struct).
No - i'm not giving a struct to QPC - just a __int64 subitem from it.
@LessBread: "LARGE_INTEGER needs an 8 byte alignment"
No. Where did you get that? Alignment of 1 is perfectly fine - just QPC triggers a error ... and somewhat rightfully so - when i think about it.
The execution time would depend on the address where the result is stored (non machine unit alignment and partial write and other odds). But for the funtion to be userful (in more demanding timings) - it's execution time should be constant. Still - it's stupid, it would make more sense to note it in spec and assume good pointers from users and not waste time for idiotic checks.
Btw: looked at intels instruction set spec (P4) and rdtsc returns it's value directly to EAX/EDX - no way to store it directly to some address.
Aah... (mouth is singing and heart is worrying) c doesn't reorder anything - delphi/pascal does that. My bad.
Found out that by placing pack(1) pragma inside struct will do what i wanted - struct itself will be aligned to 4 and data in it to 1 (without inserting space to the end of struct).
No - i'm not giving a struct to QPC - just a __int64 subitem from it.
@LessBread: "LARGE_INTEGER needs an 8 byte alignment"
No. Where did you get that? Alignment of 1 is perfectly fine - just QPC triggers a error ... and somewhat rightfully so - when i think about it.
The execution time would depend on the address where the result is stored (non machine unit alignment and partial write and other odds). But for the funtion to be userful (in more demanding timings) - it's execution time should be constant. Still - it's stupid, it would make more sense to note it in spec and assume good pointers from users and not waste time for idiotic checks.
Btw: looked at intels instruction set spec (P4) and rdtsc returns it's value directly to EAX/EDX - no way to store it directly to some address.
Quote:\Me looks at QPC assembly: LOL, forget what i said. The way it does it - well, even if i call my grandmother and ask for time i'l likely get a more acurate answer. (Maybe not that bad, but you get the point).
Original post by randomname
(non machine unit alignment and partial write and other odds)
Quote:
Original post by randomname
@LessBread: "LARGE_INTEGER needs an 8 byte alignment"
No. Where did you get that? Alignment of 1 is perfectly fine - just QPC triggers a error ... and somewhat rightfully so - when i think about it.
From Jeff Ricther's Advanced Windows 3rd Ed. page 446 in the discussion on SetWaitableTimer, "The address of all FILETIME structures must begin on an even 32-bit boundary, but the address of all LARGE_INTEGER structures must begin on an even 64-bit boundary."
The quote remains in the 4th edition (retitled "Programming Applications") in Chapter 9, "Waitable Timer Kernel Objects".
I see. Thanks. Did change the 8byte values to 8byte alignment anyway.
Why does Windows make such a pointless (look my previous post) constraint?
Why does Windows make such a pointless (look my previous post) constraint?
Quote:
Why does Windows make such a pointless (look my previous post) constraint?
hehe, not pointless.
Clues:
1) read the article LessBread provided about CPU alignment constraints (IA-32 pampers you; IA-64 does not).
2) the .QuadPart member allows the LARGE_INTEGER struct to be used as one 64-bit number.
Final piece of the puzzle: Windows API calls have to make sure user-specified addresses are valid before writing there. Due to the above, alignment checks are a part of that.
Quote:
Me looks at QPC assembly: LOL, forget what i said. The way it does it - well, even if i call my grandmother and ask for time i'l likely get a more acurate answer.
hmm. Why? What did you see there?
@Jan Wassenberg:
It's not timers job to care. A timer must have as less code as possible. But yeah - seems that QPC has got a lot of stuff todo (valid/aligned).
Win should provide a timer that does return its result in register(s) - me thinks.
"hmm. Why? What did you see there?"
Too much code ... just too much (i didn't even find the place where it gets the final value - it's prety annioning to trace. [especially as goes to int{whatever its number was} prety fast]).
It's not timers job to care. A timer must have as less code as possible. But yeah - seems that QPC has got a lot of stuff todo (valid/aligned).
Win should provide a timer that does return its result in register(s) - me thinks.
"hmm. Why? What did you see there?"
Too much code ... just too much (i didn't even find the place where it gets the final value - it's prety annioning to trace. [especially as goes to int{whatever its number was} prety fast]).
Quote:
It's not timers job to care. A timer must have as less code as possible. But yeah - seems that QPC has got a lot of stuff todo (valid/aligned).
hehe. As annoying as it may seem, each routine that runs at CPL0 has to be paranoid about writing to memory. Mess up once, and the security of the entire system is compromised.
Quote:
Win should provide a timer that does return its result in register(s) - me thinks.
Windows is in theory portable, so you can't just specify that results go in e.g. edx:eax. There is such a calling convention on x86, but the C language return value is dedicated to returning the status (questionable but legit design decision).
Quote:
Too much code ... just too much (i didn't even find the place where it gets the final value - it's prety annioning to trace. [especially as goes to int{whatever its number was} prety fast]).
No one said QPC was simple :)
BTW, its complexity increases accuracy instead of the opposite - e.g. there is code to synchronize the timestamp counters between CPUs (on SMP systems). Now that would've been useful, if they hadn't gotten it wrong on earlier systems, and now everyone's writing their own workarounds.. sigh ;)
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement