# [Pkg] The Trunk: Kernel-nice.725.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Jan 1 15:48:34 UTC 2013

```Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.725.mcz

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

Name: Kernel-nice.725
Author: nice
Time: 1 January 2013, 4:47:30.911 pm
Ancestors: Kernel-nice.724

Fast-up large integer modulo operations (\\ and rem:)

Implementation notes:
Quotient and remainder are computed in a single LargeIntegersPlugin primitive (see digitDiv:neg:) so it's faster to just use it.
For LargeInteger with 64 bits or less, LargeInteger primitives (31 32 33) are faster than the plugin (especially in COG) so try them first.
This results in a 2x speed up of modulo operations in 4.2.5 VM (whatever bit length), and a 2x speed up in COG VM for bit length > 64.
There is a penalty of 15% in COG for #rem: when bit length <= 64 because there is no primitiveRem...
Well, I added primitiveRem and it is in both VM branches, but it has no primitive number assigned.
If we assign a primitive number (20 ?) we can expect a 5x speed up for rem and bitLength <= 64.

=============== Diff against Kernel-nice.724 ===============

Item was changed:
----- Method: LargePositiveInteger>>\\ (in category 'arithmetic') -----
+ \\ aNumber
- \\ anInteger
"Primitive. Take the receiver modulo the argument. The result is the
remainder rounded towards negative infinity, of the receiver divided
by the argument. Fail if the argument is 0. Fail if either the argument
or the result is not a SmallInteger or a LargePositiveInteger less than
2-to-the-30th (1073741824). Optional. See Object documentation whatIsAPrimitive."

<primitive: 31>
+ 	aNumber isInteger
+ 		ifTrue:
+ 			[| neg qr q r |
+ 			neg := self negative == aNumber negative == false.
+ 			qr := (self digitDiv:
+ 				(aNumber class == SmallInteger
+ 					ifTrue: [aNumber abs]
+ 					ifFalse: [aNumber])
+ 				neg: neg).
+ 			q := qr first normalize.
+ 			r := qr last normalize.
+ 			^(q negative
+ 				ifTrue: [r isZero not]
+ 				ifFalse: [q isZero and: [neg]])
+ 					ifTrue: [r + aNumber]
+ 					ifFalse: [r]].
+ 	^super \\ aNumber
+ 	!
- 	^super \\ anInteger!

+ ----- Method: LargePositiveInteger>>primitiveQuo: (in category 'private') -----
+ primitiveQuo: anInteger
+ 	"Primitive. Divide the receiver by the argument and return the result.
+ 	Round the result down towards zero to make it a whole integer. Fail if
+ 	the argument is 0. Fail if either the argument or the result is not a
+ 	SmallInteger or a LargePositiveInteger less than 2-to-the-30th (1073741824). Optional. See
+ 	Object documentation whatIsAPrimitive."
+
+ 	<primitive: 33>
+ 	^nil!

+ ----- Method: LargePositiveInteger>>rem: (in category 'arithmetic') -----
+ rem: aNumber
+ 	"Remainder defined in terms of quo:. See super rem:.
+ 	This is defined only to speed up case of very large integers."
+
+ 	(self primitiveQuo: aNumber)
+ 		ifNotNil: [:quo | ^self - (quo * aNumber)].
+ 	 aNumber isInteger
+ 		ifTrue:
+ 			[| ng rem |
+ 			ng := self negative == aNumber negative == false.
+ 			rem := (self digitDiv:
+ 				(aNumber class == SmallInteger
+ 					ifTrue: [aNumber abs]
+ 					ifFalse: [aNumber])
+ 				neg: ng) at: 2.
+ 			^ rem normalize].
+ 	^super rem: aNumber!

```