[squeak-dev] The Trunk: Chronology-Core-nice.41.mcz

commits at source.squeak.org commits at source.squeak.org
Mon May 6 07:08:18 UTC 2019


Nicolas Cellier uploaded a new version of Chronology-Core to project The Trunk:
http://source.squeak.org/trunk/Chronology-Core-nice.41.mcz

==================== Summary ====================

Name: Chronology-Core-nice.41
Author: nice
Time: 23 April 2019, 11:52:55.257088 pm
UUID: e4abf0f8-228d-4456-b296-92764394926c
Ancestors: Chronology-Core-dtl.40

Provide access to high resolution clock (if any).

This is especially useful for micro-benchmarks, so provide a #durationToRun: based on high-res clock if available.
As the name tells, it will answer a Duration rather than a number of milliseconds, microseconds or whatever...
A duration is way more universal and self-explaining than currently obscure Integer encoding returned by:

	[100 factorial] timeToRun.

The aim is either to provide a new #durationToRun selector, or replace #timeToRun semantics...

Provide a microsecondsToRun: fallback in case the host does not provide a high resolution clock.

Notes: the number of ticks per millisecond for the high-res clock is roughly estimated by a busy loop like found in the AndreasSystemProfiler.
It is reset at startup, and initialized once at first use with the assumption that it will be constant.

=============== Diff against Chronology-Core-dtl.40 ===============

Item was changed:
  Magnitude subclass: #Time
  	instanceVariableNames: 'seconds nanos'
+ 	classVariableNames: 'ClockPolicy HighResClockTicksPerMillisecond LastClockTick'
- 	classVariableNames: 'ClockPolicy LastClockTick'
  	poolDictionaries: 'ChronologyConstants'
  	category: 'Chronology-Core'!
  
  !Time commentStamp: 'dew 10/23/2004 17:58' prior: 0!
  This represents a particular point in time during any given day.  For example, '5:19:45 pm'.
  
  If you need a point in time on a particular day, use DateAndTime.  If you need a duration of time, use Duration.
  !

Item was added:
+ ----- Method: Time class>>durationToRun: (in category 'general inquiries') -----
+ durationToRun: timedBlock
+ 	"Answer a duration timedBlock takes to return its value.
+ 	Use high resolution clock if available."
+ 
+ 	| ticks |
+ 	self highResClock = 0 ifTrue: [^Duration nanoSeconds: 1000 * (self microsecondsToRun: timedBlock)].
+ 	ticks := self highResClock.
+ 	timedBlock value.
+ 	ticks := self highResClock - ticks.
+ 	^Duration nanoSeconds: 1000000* ticks // self highResClockTicksPerMillisecond!

Item was added:
+ ----- Method: Time class>>estimateHighResClockTicksPerMillisecond (in category 'clock') -----
+ estimateHighResClockTicksPerMillisecond
+ 
+ 	| t0 t1 t2 t3 |
+ 	
+ 	"Count the ticks ellapsed during a 10ms busy loop"
+ 	t0 := Time utcMicrosecondClock + 200.
+ 	[Time utcMicrosecondClock >= t0] whileFalse.
+ 	t1 := Smalltalk highResClock.
+ 	[Time utcMicrosecondClock >= (t0 + 10000)] whileFalse.
+ 	t1 := Smalltalk highResClock - t1 * 1000 // (Time utcMicrosecondClock - t0).
+ 	
+ 	"Count the ticks ellapsed during a 20ms busy loop"
+ 	t0 := Time utcMicrosecondClock + 200.
+ 	[Time utcMicrosecondClock >= t0] whileFalse.
+ 	t2 := Smalltalk highResClock.
+ 	[Time utcMicrosecondClock >= (t0 + 20000)] whileFalse.
+ 	t2 := Smalltalk highResClock - t2 * 1000 // (Time utcMicrosecondClock - t0).
+ 	
+ 	"Count the ticks ellapsed during a 30ms busy loop"
+ 	t0 := Time utcMicrosecondClock + 200.
+ 	[Time utcMicrosecondClock >= t0] whileFalse.
+ 	t3 := Smalltalk highResClock.
+ 	[Time utcMicrosecondClock >= (t0 + 30000)] whileFalse.
+ 	t3 := Smalltalk highResClock - t3 * 1000 // (Time utcMicrosecondClock - t0).
+ 	
+ 	"Take the median of the 3 estimates as the best"
+ 	^ t1 <= t2
+ 		ifTrue: [t2 <= t3
+ 				ifTrue: [t2]
+ 				ifFalse: [t1 <= t3
+ 						ifTrue: [t3]
+ 						ifFalse: [t1]]]
+ 		ifFalse: [t1 <= t3
+ 				ifTrue: [t1]
+ 				ifFalse: [t2 <= t3
+ 						ifTrue: [t3]
+ 						ifFalse: [t2]]]!

Item was added:
+ ----- Method: Time class>>highResClock (in category 'clock') -----
+ highResClock
+ 	"Time highResClock"
+ 	"Primitive. Answer the value of the high resolution clock if this computer has one.
+ 	Usually, this should be the highest resolution value available, for example on Intel
+ 	it will be the value of the time stamp counter register."
+ 	<primitive: 'primitiveHighResClock'>
+ 	^0!

Item was added:
+ ----- Method: Time class>>highResClockTicksPerMillisecond (in category 'clock') -----
+ highResClockTicksPerMillisecond
+ 	HighResClockTicksPerMillisecond = 0
+ 		ifTrue:
+ 			[HighResClockTicksPerMillisecond := self estimateHighResClockTicksPerMillisecond].
+ 	^HighResClockTicksPerMillisecond!

Item was changed:
  ----- Method: Time class>>initialize (in category 'class initialization') -----
  initialize
  	"Time initialize"
  
  	"Initialize at startup time to protect for the case of an image saved with bad LastClockTick"
  	LastClockTick := 0.
+ 	
+ 	HighResClockTicksPerMillisecond := 0.
  
  	"self clockPolicy: #acceptPlatformTime."
  	self clockPolicy: #monotonicAllowDuplicates.
  	"self clockPolicy: #monotonicForceMicrosecondIncrement."
  	"self clockPolicy: #monotonicForceNanosecondIncrement."
  !

Item was added:
+ ----- Method: Time class>>microsecondsToRun: (in category 'general inquiries') -----
+ microsecondsToRun: timedBlock 
+ 	"Answer the number of microseconds timedBlock takes to return its value."
+ 
+ 	| startUsecs |
+ 	startUsecs := self utcMicrosecondClock.
+ 	timedBlock value.
+ 	^self utcMicrosecondClock - startUsecs!

Item was changed:
  ----- Method: Time class>>millisecondsToRun: (in category 'general inquiries') -----
  millisecondsToRun: timedBlock 
  	"Answer the number of milliseconds timedBlock takes to return its value."
  
+ 	^(self microsecondsToRun: timedBlock) + 500 // 1000!
- 	| startUsecs |
- 	startUsecs := self utcMicrosecondClock.
- 	timedBlock value.
- 	^self utcMicrosecondClock - startUsecs + 500 // 1000!



More information about the Squeak-dev mailing list