Thread overview
Question: 64 bit integer arithmetic on Win32
Mar 26, 2006
Nicholas Jordan
Mar 27, 2006
Nic Tiger
Mar 28, 2006
Jan Knepper
Mar 28, 2006
Jan Knepper
Mar 28, 2006
Nicholas Jordan
Mar 28, 2006
Nic Tiger
Mar 29, 2006
Nicholas Jordan
March 26, 2006
I am writing much of my core modules in "dos box"
- i.e. Command line interface -
(without #including windows.h)
style because because this style lends it's self to quick switching between
coding and trial runs .... I have noticed that if I try to read in a large file,
say ~65k, the performance of the disk accesses is *vastly* different from that
of the code that is already in the L2 cache or RAM.

My entire design philosophy rests on code-compile-test,code-compile-test,code-compile-test,code-compile-test.... so this morning I tried to write an RDTSC stubb to begin looking at what chunk size inter-leaves fluidly with other parts of the program; and ran up against the question of what exactly gets assembled for example psuedo code:

__int64 val_1(0x0000),val_2(0x0000),tmp_;
asm{RDTSC,MOV tmp_ eax,MOV tmp_+4 ecx,}
val_1 = tmp;
/*......code under test........*/
asm{RDTSC,MOV tmp_,eax,MOV tmp_+4 ecx}
val_2 = tmp_;
tmp_ =  val_2 - val_1;

Does that last line do 64-bit integer arithmetic, or does it set me up for an embarrasing ride on the Blunder Bus ?



Mission Statement: Belvedere Computer Services
http://www.docdubya.com/belvedere/statement/index.html
It is the intent of Belvedere Computer Services to find and conduct legitimate
business in free markets using the skills discussed in this document.
Nick's law: "The only dumb question is one you should have asked and didn't."
March 27, 2006
I use this code to get rdtsc

#include <stdint.h>

int64_t getCpuTicksCount () {
  int64_t t;
  asm {
    rdtsc
    mov dword ptr t, eax
    mov dword ptr t+4, edx
  }
  return t;
}

Also, note that time is returned in edx:eax pair, not ecx:eax as in your
code
Nic Tiger

"Nicholas Jordan" <Nicholas_member@pathlink.com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ ÓÌÅÄÕÀÝÅÅ: news:e07195$1ldv$1@digitaldaemon.com...
> __int64 val_1(0x0000),val_2(0x0000),tmp_;
> asm{RDTSC,MOV tmp_ eax,MOV tmp_+4 ecx,}
> val_1 = tmp;
> /*......code under test........*/
> asm{RDTSC,MOV tmp_,eax,MOV tmp_+4 ecx}
> val_2 = tmp_;
> tmp_ =  val_2 - val_1;
>
> Does that last line do 64-bit integer arithmetic, or does it set me up for
> an
> embarrasing ride on the Blunder Bus ?
>
> Mission Statement: Belvedere Computer Services
> http://www.docdubya.com/belvedere/statement/index.html
> It is the intent of Belvedere Computer Services to find and conduct
> legitimate
> business in free markets using the skills discussed in this document.
> Nick's law: "The only dumb question is one you should have asked and
> didn't."


March 28, 2006
Oh, I think it is every easier than that...

inline int64  getCpuTicksCount ()
{
   __asm rdtsc
}

;-)

Jan



Nic Tiger wrote:
> I use this code to get rdtsc
> 
> #include <stdint.h>
> 
> int64_t getCpuTicksCount () {
>   int64_t t;
>   asm {
>     rdtsc
>     mov dword ptr t, eax
>     mov dword ptr t+4, edx
>   }
>   return t;
> }
> 
> Also, note that time is returned in edx:eax pair, not ecx:eax as in your code
> Nic Tiger
> 
> "Nicholas Jordan" <Nicholas_member@pathlink.com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ ÓÌÅÄÕÀÝÅÅ: news:e07195$1ldv$1@digitaldaemon.com...
>> __int64 val_1(0x0000),val_2(0x0000),tmp_;
>> asm{RDTSC,MOV tmp_ eax,MOV tmp_+4 ecx,}
>> val_1 = tmp;
>> /*......code under test........*/
>> asm{RDTSC,MOV tmp_,eax,MOV tmp_+4 ecx}
>> val_2 = tmp_;
>> tmp_ =  val_2 - val_1;
>>
>> Does that last line do 64-bit integer arithmetic, or does it set me up for an
>> embarrasing ride on the Blunder Bus ?
>>
>> Mission Statement: Belvedere Computer Services
>> http://www.docdubya.com/belvedere/statement/index.html
>> It is the intent of Belvedere Computer Services to find and conduct legitimate
>> business in free markets using the skills discussed in this document.
>> Nick's law: "The only dumb question is one you should have asked and didn't." 
> 
> 


-- 
ManiaC++
Jan Knepper

But as for me and my household, we shall use Mozilla...
www.mozilla.org
March 28, 2006
Jan Knepper wrote:
Oh... One more thing... when you're running HT or Dual Core you might be in trouble accessing this... as TSC (Time Stamp Counter)'s between Core's seem to get out of sync...
So what you would have to do on NT for instance is.

DWORD   tam = SetThreadAffinityMask ( 1 );
QWORD	tcs = getCpuTicksCount ();

SetThreadAffinityMask ( tam );

This forces the the rdtsc to be executed on the first processor.

Jan



> Oh, I think it is every easier than that...
> 
> inline int64  getCpuTicksCount ()
> {
>    __asm rdtsc
> }
> 
> ;-)
> 
> Jan
> 
> 
> 
> Nic Tiger wrote:
>> I use this code to get rdtsc
>>
>> #include <stdint.h>
>>
>> int64_t getCpuTicksCount () {
>>   int64_t t;
>>   asm {
>>     rdtsc
>>     mov dword ptr t, eax
>>     mov dword ptr t+4, edx
>>   }
>>   return t;
>> }
>>
>> Also, note that time is returned in edx:eax pair, not ecx:eax as in your code
>> Nic Tiger
>>
>> "Nicholas Jordan" <Nicholas_member@pathlink.com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ ÓÌÅÄÕÀÝÅÅ: news:e07195$1ldv$1@digitaldaemon.com...
>>> __int64 val_1(0x0000),val_2(0x0000),tmp_;
>>> asm{RDTSC,MOV tmp_ eax,MOV tmp_+4 ecx,}
>>> val_1 = tmp;
>>> /*......code under test........*/
>>> asm{RDTSC,MOV tmp_,eax,MOV tmp_+4 ecx}
>>> val_2 = tmp_;
>>> tmp_ =  val_2 - val_1;
>>>
>>> Does that last line do 64-bit integer arithmetic, or does it set me up for an
>>> embarrasing ride on the Blunder Bus ?
>>>
>>> Mission Statement: Belvedere Computer Services
>>> http://www.docdubya.com/belvedere/statement/index.html
>>> It is the intent of Belvedere Computer Services to find and conduct legitimate
>>> business in free markets using the skills discussed in this document.
>>> Nick's law: "The only dumb question is one you should have asked and didn't." 
>>
>>
> 
> 


-- 
ManiaC++
Jan Knepper

But as for me and my household, we shall use Mozilla...
www.mozilla.org
March 28, 2006
In article <e0a3vr$2n9$1@digitaldaemon.com>, Jan Knepper says...

Do not know what 'HT or Dual Core' means, will assume hyper-threading and dual-processor or something of the sort .... that's a ways off ~ still working base functionality....trying to work around limitations of Win32 "security model" to implement screens to keep out pests.

Will use:
inline int64  getCpuTicksCount (void){__asm rdtsc}// Timer
in methods.h, but is #include <stdint.h> necessary for the code to compile
corrctly in Win32 (and it's interface as exposed in NT compilation model)

I have gone to writing trace files as it's easier for me (faster) that using the debugger - so it's only the compiled code that I am worried about.

I cannot read the assembly listing effectively, 'scuse  the edx:eax / ecx:eax pair mistake, ....

>
>Jan Knepper wrote:
>Oh... One more thing... when you're running HT or Dual Core you might be
>in trouble accessing this... as TSC (Time Stamp Counter)'s between
>Core's seem to get out of sync...
>So what you would have to do on NT for instance is.
>
>DWORD   tam = SetThreadAffinityMask ( 1 );
>QWORD	tcs = getCpuTicksCount ();
>
>SetThreadAffinityMask ( tam );
>
>This forces the the rdtsc to be executed on the first processor.
>
>Jan
>
>
>
>> Oh, I think it is every easier than that...
>> 
>> inline int64  getCpuTicksCount ()
>> {
>>    __asm rdtsc
>> }
>> 
>> ;-)
>> 
>> Jan
>> 
>> 
>> 
>> Nic Tiger wrote:
>>> I use this code to get rdtsc
>>>
>>> #include <stdint.h>
>>>
>>> int64_t getCpuTicksCount () {
>>>   int64_t t;
>>>   asm {
>>>     rdtsc
>>>     mov dword ptr t, eax
>>>     mov dword ptr t+4, edx
>>>   }
>>>   return t;
>>> }
>>>
>>> Also, note that time is returned in edx:eax pair, not ecx:eax as in
>>> your code
>>> Nic Tiger
>>>
>>> "Nicholas Jordan" <Nicholas_member@pathlink.com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ ÓÌÅÄÕÀÝÅÅ: news:e07195$1ldv$1@digitaldaemon.com...
>>>> __int64 val_1(0x0000),val_2(0x0000),tmp_;
>>>> asm{RDTSC,MOV tmp_ eax,MOV tmp_+4 ecx,}
>>>> val_1 = tmp;
>>>> /*......code under test........*/
>>>> asm{RDTSC,MOV tmp_,eax,MOV tmp_+4 ecx}
>>>> val_2 = tmp_;
>>>> tmp_ =  val_2 - val_1;
>>>>
>>>> Does that last line do 64-bit integer arithmetic, or does it set me
>>>> up for an
>>>> embarrasing ride on the Blunder Bus ?
>>>>
>>>> Mission Statement: Belvedere Computer Services
>>>> http://www.docdubya.com/belvedere/statement/index.html
>>>> It is the intent of Belvedere Computer Services to find and conduct
>>>> legitimate
>>>> business in free markets using the skills discussed in this document.
>>>> Nick's law: "The only dumb question is one you should have asked and
>>>> didn't."
>>>
>>>
>> 
>> 
>
>
>-- 
>ManiaC++
>Jan Knepper
>
>But as for me and my household, we shall use Mozilla... www.mozilla.org


March 28, 2006
Nicholas Jordan wrote:
> Will use: inline int64  getCpuTicksCount (void){__asm rdtsc}// Timer
> in methods.h, but is #include <stdint.h> necessary for the code to compile
> corrctly in Win32 (and it's interface as exposed in NT compilation model)
> 

You can use __int64 - it is built-in type, so no headers needed

(as for me, I like uint64_t - styled types, but unfortunately stdint.h is missing in VC6 and VS2003, so it is a bit non-portable)
March 29, 2006
In article <e0buoc$2v6v$1@digitaldaemon.com>, Nic Tiger says...
>
>Nicholas Jordan wrote:
>> Will use:
>> inline int64  getCpuTicksCount (void){__asm rdtsc}// Timer
>> in methods.h, but is #include <stdint.h> necessary for the code to compile
>> corrctly in Win32 (and it's interface as exposed in NT compilation model)
>> 
>
>You can use __int64 - it is built-in type, so no headers needed
>
>(as for me, I like uint64_t - styled types, but unfortunately stdint.h is missing in VC6 and VS2003, so it is a bit non-portable)

Meet me in cpp/chat if you are interested in my comments on VC, but expect 10k responses to minor nuances.

What follows is my work from this morning in case you may wish to provide review

in L:\itc\stdint.h

#define __LONGLONG (__INTSIZE == 4)

line 72  [L:\itc\stdint.h]

typedef long long int64_t;

unless I
#include <stdint.h>
I get:
Error: I:\test_source.cpp(11): undefined identifier 'int64_t'

but testing reveals:

__int64 StartClock;
int64_t EndClock;

sizeof(StartClock) == 8
sizeof(EndClock) == 8

So it would seem - in the compiled code - that
I can use either one, but the operation of
skinny-winnie where the raster-ops can
literally hang the entire platform makes for a
real sense of desperation when I think about
the real world where this might run - where it
matters quite alot in the sense of not
introducing subtle pestilence that does not
show up in test-harness(s) that I can write
with limited skills that do not understand lex
and yacc

example:

{
__asm rdtsc
}

or:

{__asm rdtsc }

to save eyespace in;
//   L:\itc\methods.h - 14228 characters, 1547 words, 403 lines

also matters (possibly) because putting white
space,such as a space or a return, between the
close parenthesis and the semicolon may be the
same (following an asm keyword) as a semicolon
in cpp compiles....

'... note that RDTSC is returned in edx:eax pair,..."

Correct, per 11-332 Vol-2:'Pentium Pro Family Developer's Manual'

And for Jan's constructive feedback that MP seems to get out of sync() for rdtsc

RDTSC is not serializing - 11-332 Vol-2:'Pentium Pro Family Developer's Manual'


A dog will treat you like one of the family.....
A cat will treat you like one of the staff.
A hard drive head reading off the platter has been compared to a Boeing 747
flying 3 feet off the ground, at mach 4, counting blades of grass
Any sufficiently optimistic statement is indistinguishable from sarcasm.