addmul_k with toom

Niels Möller nisse at lysator.liu.se
Sun Jun 18 19:53:55 UTC 2017


nisse at lysator.liu.se (Niels Möller) writes:

> Writing up an addmul_2 for intel atom using toom2 is probably the most
> promising step in this direction.

Below is an assembly sketch, not yet working. With some luck, some
variant of this should run in 54 cycles per iteration on Atom (limited
by multiplication throughput, each of the three muls taking 18 cycles).
Not sure how to think about scheduling for this processor (and it's
little point in thinking too much about it until we have a correct
instruction sequence).

If it can be made to work, time per each limb product would be reduced
from 19 to 14 cycles. Going from toom2 to toom32, one could
theoretically get down to 12 cycles, but unlikely to get the needed
values to fit in available registers.

Regards,
/Niels

dnl  AMD64 mpn_addmul_2 optimised for Intel Atom.

dnl  Copyright 2008, 2011-2013, 2017 Free Software Foundation, Inc.

dnl  This file is part of the GNU MP Library.
dnl
dnl  The GNU MP Library is free software; you can redistribute it and/or modify
dnl  it under the terms of either:
dnl
dnl    * the GNU Lesser General Public License as published by the Free
dnl      Software Foundation; either version 3 of the License, or (at your
dnl      option) any later version.
dnl
dnl  or
dnl
dnl    * the GNU General Public License as published by the Free Software
dnl      Foundation; either version 2 of the License, or (at your option) any
dnl      later version.
dnl
dnl  or both in parallel, as here.
dnl
dnl  The GNU MP Library is distributed in the hope that it will be useful, but
dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
dnl  for more details.
dnl
dnl  You should have received copies of the GNU General Public License and the
dnl  GNU Lesser General Public License along with the GNU MP Library.  If not,
dnl  see https://www.gnu.org/licenses/.

include(`../config.m4')

C	     cycles/limb	best
C AMD K8,K9
C AMD K10
C AMD bd1
C AMD bd2
C AMD bobcat
C AMD jaguar
C Intel P4
C Intel PNR
C Intel NHM
C Intel SBR
C Intel IBR
C Intel HWL
C Intel BWL
C Intel atom	18.8		this
C VIA nano

define(`rp',      `%rdi')   C rcx
define(`up',      `%rsi')   C rdx
define(`n_param', `%rdx')   C r8
define(`vp',      `%rcx')   C r9

define(`v0', `%r8')
define(`v1', `%r9')
define(`c0', `%rbx')
define(`c1', `%rcx')	C Overlaps vp
define(`vm1', `%rbp')
define(`vs', `%r10')
define(`n',  `%r11')
define(`u0', `%r12')
define(`um1', `%r13')
define(`us', `%r14')
define(`p0', `%r12')	C Overlaps u0
define(`p1', `%r15')	
define(`p2', `%r13')	C Overlaps um1
C FIXME: Either move around so we can overlap us,
C or move loop counter to the stack.	
define(`p3', `%r11')	C Overlaps n, with extra save and restore
	
ABI_SUPPORT(DOS64)
ABI_SUPPORT(STD64)

ASM_START()
	TEXT
	ALIGN(16)
PROLOGUE(mpn_addmul_2)
	FUNC_ENTRY(4)
	push	%rbx
	push	%rbp

	mov	(vp), v0
	mov	8(vp), v1

	mov	n_param, n
	xor	c0, c0
	xor	c1, c1

	test	$1, R8(n)
	jz	L(even)

	mov	(up), %rax
	mov	%rax, u0
	mul	v0

	add	%rax, (rp)
	adc	%rdx, c0
	mov	u0, %rax
	mul	v1
	add	%rax, c0
	adc	%rax, c1	
	dec	n
	lea	8(rp), rp
	lea	8(up), up
	jz 	L(end)
L(even):
	push	%r12
	push	%r13
	push	%r14
	push	%r15
	mov	v0, vm1
	sub	v1, vm1
	sbb	vs, vs
	// Negate
	xor	vs, vm1
	sub	vs, vm1
	not	vs
	shr	n
L(top):
	push	n
	mov	(up), %rax
	mov	%rax, u0
	mul	v0
	mov	%rax, p0
	mov	%rdx, p1
	mov	8(up), %rax
	mov	u0, um1
	sub	%rax, um1
	sbb	us, us
	mul	v1
	xor	us, um1
	sub	us, um1
	xor	vs, us
	xor	p3, p3
	add	%rdx, p1
	adc	%rax, p3
	C p3 p3 p0 p0
	C    p1 p1
	mov	um1, %rax
	mul	vm1

	mov	p1, p2
	add	p0, p1
	adc	p3, p2
	adc	$0, p3

	C Negate pm1
	xor	us, %rax
	xor	us, %rdx
	cmp	$-1, us		C Does this set the carry correctly?
	C FIXME: Do as carry in to some other addition.
	adc	$0, %rax
	adc	$0, %rdx
	
	C p3  p2  p1 p0
	C us rdx rax
	C         c1 c0
	C         r1 r0
	C -------------
	C c1  c0  r1 r0

	add	c0, p0
	adc	c1, p1
	xor	c0, c0
	mov	us, c1
	adc	$0, c0
	add	%rax, p1
	adc	%rdx, c0
	adc	$0, c1
	
	add	p0, (rp)
	adc	p1, 8(rp)
	adc	p2, c0
	adc	p3, c1
	pop	n
	dec	n
	lea	16(up), up
	lea	16(rp), rp
	jnz	L(top)
	pop	%r15
	pop	%r14
	pop	%r13
	pop	%r12
	
L(end):
	mov	c0, (rp)
	mov	c1, %rax
	pop	%rbp
	pop	%rbx
	FUNC_EXIT()
	ret
EPILOGUE()

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list