Nicolas Cellier uploaded a new version of Chronology-Core to project The Trunk:
http://source.squeak.org/trunk/Chronology-Core-nice.42.mcz ==================== Summary ==================== Name: Chronology-Core-nice.42 Author: nice Time: 26 April 2019, 7:27:43.413216 pm UUID: fd909f2b-275e-f44c-91fa-076eb32d64c7 Ancestors: Chronology-Core-nice.41 Make usage of highResolution clock for block-timing a Preference. This is because TSC are not reliable enough on old CPU (or not available). Always print duration subseconds by group of 3 digits (ms, us, ns) =============== Diff against Chronology-Core-nice.41 =============== Item was changed: ----- Method: Duration>>printOn: (in category 'squeak protocol') ----- printOn: aStream "Format as per ANSI 5.8.2.16: [-]D:HH:MM:SS[.S]" | d h m s n | d := self days abs. h := self hours abs. m := self minutes abs. s := self seconds abs truncated. n := self nanoSeconds abs. self negative ifTrue: [ aStream nextPut: $- ]. d printOn: aStream. aStream nextPut: $:. h < 10 ifTrue: [ aStream nextPut: $0. ]. h printOn: aStream. aStream nextPut: $:. m < 10 ifTrue: [ aStream nextPut: $0. ]. m printOn: aStream. aStream nextPut: $:. s < 10 ifTrue: [ aStream nextPut: $0. ]. s printOn: aStream. n = 0 ifFalse: [ | z ps | aStream nextPut: $.. ps := n printString padded: #left to: 9 with: $0. z := ps findLast: [ :c | c asciiValue > $0 asciiValue ]. + ps from: 1 to: z + 2 // 3 * 3 do: [ :c | aStream nextPut: c ] ] - ps from: 1 to: z do: [ :c | aStream nextPut: c ] ] ! Item was changed: Magnitude subclass: #Time instanceVariableNames: 'seconds nanos' + classVariableNames: 'ClockPolicy HighResClockTicksPerMillisecond LastClockTick UseHighResClockForTiming' - classVariableNames: 'ClockPolicy HighResClockTicksPerMillisecond 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 changed: ----- Method: Time class>>durationToRun: (in category 'general inquiries') ----- durationToRun: timedBlock + "Answer a duration timedBlock takes to return its value" - "Answer a duration timedBlock takes to return its value. - Use high resolution clock if available." + ^(self nanosecondsToRun: timedBlock) nanoSeconds! - | 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 changed: ----- Method: Time class>>microsecondsToRun: (in category 'general inquiries') ----- microsecondsToRun: timedBlock "Answer the number of microseconds timedBlock takes to return its value." | startUsecs | + (self useHighResClockForTiming and: [self highResClock ~= 0]) + ifTrue: [ ^(self nanosecondsToRunHighRes: timedBlock) + 500 // 1000]. startUsecs := self utcMicrosecondClock. timedBlock value. ^self utcMicrosecondClock - startUsecs! Item was added: + ----- Method: Time class>>nanosecondsToRun: (in category 'general inquiries') ----- + nanosecondsToRun: timedBlock + "Answer the number of nanoseconds timedBlock takes to return its value. + Use high resolution clock if available and preferred." + + | startUsecs | + (self useHighResClockForTiming and: [self highResClock ~= 0]) + ifTrue: [ ^(self nanosecondsToRunHighRes: timedBlock)]. + "Fallback to microseconds clock" + startUsecs := self utcMicrosecondClock. + timedBlock value. + ^self utcMicrosecondClock - startUsecs * 1000! Item was added: + ----- Method: Time class>>nanosecondsToRunHighRes: (in category 'general inquiries') ----- + nanosecondsToRunHighRes: timedBlock + "Answer the number of nanoseconds timedBlock takes to return its value using high resolution clock. + This assumes that high resolution clock is available, has a constant rate, and is synchronized between multi-core CPU" + + | ticks | + ticks := self highResClock. + timedBlock value. + ^(self highResClock - ticks + + (self highResClock - self highResClock ) "subtract the ticks taken by the call to highResClock itself" + * 1e6 // self highResClockTicksPerMillisecond) "and convert ticks to nanoSeconds"! Item was added: + ----- Method: Time class>>useHighResClockForTiming (in category 'preferences') ----- + useHighResClockForTiming + <preference: 'Use high resolution clock for timing' + category: 'performance' + description: 'This is used for measuring time ellapsed for running a block. High resolution clocks (known as TSC) are counter embedded on CPU and incremented at each cycle. They enable timing close to the nanosecond for GHz CPU. However, on older models, they might have a non constant rate depending on power saving: converting ticks to seconds is not reliable in this case, but knowing the number of cycles taken to perform the task is still a valuable information. TSC might also be un-synchronized between the multi-cores: if Squeak process is switched from 1 core to another during the timing, timing results could be random. If you have a recent CPU, you might prefer this option' + type: #Boolean> + ^UseHighResClockForTiming ifNil: [ false ]! |
Free forum by Nabble | Edit this page |