Nicolas Cellier uploaded a new version of Chronology-Core to project The Inbox:
http://source.squeak.org/inbox/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! |
Free forum by Nabble | Edit this page |