¿Por qué redondear al más cercano con ties alejados de cero requiere más instrucciones y cuál es su propósito?
Considere el este ejemplo, en el que varias operaciones de redondeo (redondeo hacia arriba, redondeo hacia abajo, redondeo hacia cero y redondeo al más cercano con redondeo hacia el par más cercano) se pueden expresar con una sola instrucción roundsd
:
use_floor(double):
roundsd xmm0, xmm0, 9
ret
use_ceil(double):
roundsd xmm0, xmm0, 10
ret
use_trunc(double):
roundsd xmm0, xmm0, 11
ret
use_nearby(double):
roundsd xmm0, xmm0, 12
ret
Mientras que el redondeo al más cercano con redondeo hacia el par más cercano requiere instrucciones adicionales:
use_round(double):
movapd xmm1, xmm0
andpd xmm0, XMMWORD PTR .LC1[rip]
orpd xmm0, XMMWORD PTR .LC0[rip]
addsd xmm0, xmm1
roundsd xmm0, xmm0, 3
ret
¿Por qué este modo de redondeo requiere más instrucciones en x86 (a diferencia de Arm) y cómo se implementan las operaciones de bits en un valor de punto flotante para obtener la semántica deseada?
davy.ai
El modo de redondeo “round-to-nearest-with-ties-away-from-zero” requiere más instrucciones en x86 porque no tiene soporte incorporado en la unidad de punto flotante. Por lo tanto, es necesario emularlo utilizando operaciones a nivel de bit en el valor de punto flotante.
La instrucción
movapd
copia el valor de entrada en un registro separado,xmm1
, para preservarlo para su uso posterior. La instrucciónandpd
enmascara el bit menos significativo del valor de entrada realizando una operación AND a nivel de bit con un valor constanteXMMWORD
llamado.LC1
. Esto efectivamente redondea el valor de entrada hacia abajo al número par más cercano. La instrucciónorpd
agrega el bit menos significativo nuevamente al valor redondeado realizando una operación OR a nivel de bit con un valor constanteXMMWORD
llamado.LC0
. Esto redondea el valor al número par más cercano con desempates hacia el infinito. La instrucciónaddsd
suma el valor de entrada original al valor redondeado antes de finalmente usar la instrucciónroundsd
para redondear al número par más cercano con desempates hacia el infinito.Estas operaciones a nivel de bit en un valor de punto flotante implementan la semántica deseada manipulando el bit menos significativo, que representa el bit menos significativo de la parte fraccional del valor de entrada. Al manipular este bit, el comportamiento de redondeo del valor de punto flotante puede ser modificado de la manera deseada, resultando en la semántica de redondeo deseada.