Los resultados no están definidos porque los efectos secundarios de b = a pueden ocurrir en cualquier punto antes del siguiente punto de secuencia que es el punto y coma.
Dima Korolev es a^=b, b^=a, a^=b;
funciona porque las comas son puntos de secuencia.
En general, desea darle al compilador la oportunidad de hacer lo correcto y solo micro-optimizar cuando mide un problema de rendimiento que vale la pena solucionar porque de lo contrario perderá mucho tiempo tanto el suyo como el de otras personas.
En este caso, std :: swap debería expandirse en línea a lo que funcione mejor para el procesador en cuestión y no lo va a superar.
- El producto de cuatro términos consecutivos de una progresión aritmética de enteros más el cuarto poder de la diferencia común es siempre un cuadrado perfecto. ¿Cómo se verifica esta identidad incorporando simetría en la notación?
- ¿Cómo puedo resolver problemas de tipo de embalaje o mochila en Excel?
- ¿Cuál es el significado del teorema de Faltings?
- ¿Cuál es el significado de la ley de reciprocidad cuadrática?
- ¿Cuál es el significado del teorema de Green-Tao?
Incluso si ese no fuera el caso, no sería mejor en la mayoría de los procesadores que la asignación con uno o más temporarios en los registros porque los conjuntos de instrucciones generalmente solo admiten un operando de memoria y hay paradas de carga.
Para fines ilustrativos, he citado la salida (sintaxis de AT&T con el operando de origen y luego de destino, que es lo opuesto a MASM) de gcc 4.7 amd64 con -O en varias implementaciones de void swap(int &lhs, int &rhs)
de void swap(int &lhs, int &rhs)
.
Nota:
- La versión con asignación simple y una variable temporal es idéntica a std :: swap.
- El compilador utiliza un par de registros en lugar de una sola variable temporal para limitar el impacto de pérdida de carga en ambos casos con dos instrucciones entre la carga de lhs y el almacén de rhs.
- La versión que usa xor tiene un almacenamiento y carga adicionales y funcionará peor de lo que sugiere el recuento de instrucciones porque los valores leídos de la memoria se usan inmediatamente después de la recuperación, por lo que nada se superpone con el retraso de carga (4 ciclos desde la caché L1 en los procesadores i7) y la pérdida de carga Los impactos se maximizan. El código permanece igual con -O9.
std :: swap (lhs, rhs); movl (% rdi),% eax movl (% rsi),% edx movl% edx, (% rdi) movl% eax, (% rsi)
int tmp; tmp = lhs; lhs = rhs; rhs = tmp; movl (% rdi),% eax movl (% rsi),% edx movl% edx, (% rdi) movl% eax, (% rsi)
lhs ^ = rhs, rhs ^ = lhs, lhs ^ = rhs; movl (% rsi),% eax xorl (% rdi),% eax movl% eax, (% rdi) xorl (% rsi),% eax movl% eax, (% rsi) xorl% eax, (% rdi)