traduccion programming computer architecture pipeline

architecture - computer - pipeline programming



Beneficios de usar la evaluaciĆ³n de cortocircuito (15)

¿Cómo puede anidado si no se para? En realidad, si a y b son variables y no expresiones con efectos secundarios, pueden ser cargadas en paralelo por un buen compilador. No hay beneficio al usar más ifs excepto aumentar el recuento de líneas. Realmente, este sería el peor tipo de adivinar un compilador.

Se llama evaluación de cortocircuito.

boolean a = false, b = true; if ( a && b ) { ... };

En la mayoría de los idiomas, b no se evaluará porque a es falso, por lo que a && b no puede ser verdadero. Mi pregunta es, ¿no sería el cortocircuito más lento en términos de arquitectura? En una tubería, ¿te quedas atascado mientras esperas obtener el resultado de a para determinar si b debe evaluarse o no? ¿Sería mejor hacer ifs anidados en su lugar? ¿Eso incluso ayuda?

Además, ¿alguien sabe lo que típicamente se llama evaluación de cortocircuito? Esta pregunta surgió después de que descubrí que mi amigo de programación nunca había oído hablar de la evaluación de cortocircuito y afirmó que no es común, ni se encuentra en muchos idiomas, y es ineficiente en la tubería. No estoy seguro del último, ¡así que les pregunto gente!

Está bien, creo que es un ejemplo diferente para quizás explicar de dónde vendrá mi amigo. Él cree que desde la evaluación de una declaración como la siguiente en paralelo:

(a) if ( ( a != null ) && ( a.equals(b) ) ) { ... }

bloqueará el sistema, una arquitectura que no tenga un cortocircuito (y por lo tanto no permita declaraciones como la anterior) sería más rápido en el procesamiento de sentencias como estas:

(b) if ( ( a == 4 ) && ( b == 5 ) )

ya que si no puede hacer (a) en paralelo, no puede hacer (b) en paralelo. En este caso, un lenguaje que permite un cortocircuito es más lento que uno que no lo hace.

No sé si eso es cierto o no.

Gracias


Dependiendo del contexto, también se puede llamar "Protección".

Y lo he visto en casi todos los idiomas en los que he trabajado, lo que empuja a casi una docena.


El cortocircuito, o evaluación mínima, es solo azúcar sintáctico para if anidados. Asumir que es ineficiente o causa pérdida es un caso de optimización prematura. En este punto, la mayoría de los compiladores son lo suficientemente inteligentes como para interpretar y optimizar estas declaraciones correctamente. El uso de estas declaraciones puede reducir enormemente la anidación y, por lo tanto, mejorar la legibilidad del código, que debería ser su objetivo número uno.


En cuanto a si el cortocircuito es o no eficiente, es poco probable que la canalización tenga un gran impacto en el rendimiento. En situaciones en las que podría tener un impacto, no hay nada que impida que el compilador pruebe varias condiciones en paralelo siempre que estas pruebas no tengan efectos secundarios. Además, las CPU modernas tienen varios mecanismos útiles para mejorar el rendimiento de la tubería del código ramificado.

El if anidado tendrá el mismo efecto que un cortocircuito &&.

La ''evaluación de cortocircuito'' es el nombre más común, y su amigo se equivoca al considerar que no es común; es muy común


Honestamente, no me preocuparía. Probar un booleano es realmente rápido . El cortocircuito solo se vuelve interesante / útil cuando la segunda expresión tiene efectos secundarios:

if ( ConfirmAction() && DestroyAllData() ) Reboot();

... o depende de la primera prueba:

if ( myDodgyVar != null && myDodgyVar.IsActive() ) DoSomethingWith(myDodgyVar);


La evaluación de cortocircuito se traduce en ramas en lenguaje ensamblador de la misma manera si las declaraciones son (las ramas son básicamente un goto), lo que significa que no va a ser más lento que las sentencias if.

Las sucursales normalmente no bloquean la canalización, pero el procesador adivinará si la rama se toma o no, y si el procesador está equivocado, tendrá que enjuagar todo lo que sucedió, ya que hizo una conjetura incorrecta de la tubería.

La evaluación de corto circuito es también el nombre más común para ella, y se encuentra en la mayoría de los idiomas de una forma u otra.


La mayoría de los lenguajes hacen una evaluación de cortocircuito de las expresiones booleanas. Siempre he oído que se lo conoce como evaluación de cortocircuito.

El ejemplo en la pregunta es un ejemplo bastante simplista que realmente no proporciona mucho beneficio de rendimiento. El beneficio de rendimiento se produce cuando las expresiones son complejas de evaluar.

Como ejemplo de cuándo sería bueno, imagine un programa de juego que tenga algo así como:

if (someObject.isActive() && someOtherObject.isActive() && CollisionDetection.collides(someObject, someOtherObject) { doSomething(); }

En este caso, la detección de colisión es mucho más costosa que las comprobaciones activas. Habría un aumento significativo en el rendimiento si hubiera muchos objetos inactivos en el sistema.


No sé nada sobre la canalización, pero la evaluación de cortocircuitos es una característica común de muchos idiomas (y ese también es el nombre por el que lo conozco). En C, && y los otros operadores definen un punto de secuencia como el; El operador sí lo hace, así que no veo cómo la evaluación de cortocircuitos es menos eficiente que simplemente usar múltiples declaraciones.


Primero, tu amigo está equivocado. La evaluación de cortocircuito (también conocida como evaluación mínima) está disponible en la mayoría de los idiomas y es mejor que los if if anidados para los lenguajes paralelos (en cuyo caso, la primera de las condiciones que devuelve hará que la ejecución continúe)

En cualquier caso, incluso en un lenguaje sencillo no paralelo, no veo cómo los ifs anidados serían más rápidos ya que la ejecución se bloquearía hasta que se evalúe la primera condición.


Solo he oído hablar de él como un cortocircuito. en una tubería ¿la próxima operación que entra depende del resultado de la declaración if? si ese es el caso, esto sería más optimizado, por lo que no tendría que probar dos valores cada vez.


Un único hilo es secuencial, así que si tienes dos ifs, el primero, por supuesto, será evaluado antes del segundo, por lo que no puedo ver una diferencia en eso. Uso el operador condicional AND (que es lo que && se llama afaik) mucho más que los if if anidados. Si quiero verificar algo que puede llevar un tiempo evaluar, hago primero la prueba más simple y luego la más difícil después del condicional y.

a = obj.somethingQuickToTest() && obj.somethingSlowToTest();

no parece ser diferente de

a = false; if(obj.somethingQuickToTest()) a = obj.somethingSlowToTest();


Un cortocircuito útil que uso es algo como esto:

if (a != null && a.equals(somevalue)) { ... do something. }

Esto es, en mi opinión, muy legible y funciona bastante bien. En general, trato de evitar mucho anidar porque conduce a un código feo.

Toda mi opinión sin embargo.


VB.Net tiene una sintaxis diferente dependiendo de si desea o no un cortocircuito. Debido a razones heredadas, el comportamiento predeterminado es no cortocircuitar. La sintaxis es la siguiente

No cortocircuito

IF A And B THEN ... END IF

Cortocircuito

IF A AndAlso B THEN ... END IF

Puede usar Or / OrElse si quiere cortocircuitar una instrucción OR. Lo cual es realmente bueno en situaciones como las siguientes

If MyObj IsNot Nothing AndAlso MyObj.Value < SomeValue Then .... End If

Personalmente, si bien entiendo que los cortocircuitos pueden acelerar las cosas, definitivamente no es algo obvio por solo mirar el código. Pude ver a un desarrollador sin experiencia confundirse por el comportamiento. Incluso parece que algo podría suceder o no según los indicadores del compilador para el nivel de optimización. Me gusta cómo VB es detallado sobre qué comportamiento realmente quiere lograr.


Idiomas que apoyan el cortocircuito:

Ada, Eiffel, ALGOL 68, C1, C ++, C #, Java, R, Erlang, ML estándar, Javascript, MATLAB, Lisp, Lua, Esquema, OCaml, Haskell, Pascal, Perl, Ruby, PHP, Python, Smalltalk, Visual Basic .RED

Tomado de la evaluación de cortocircuito


Las expresiones booleanas en cortocircuito son exactamente equivalentes a algún conjunto de if anidados, por lo que son tan eficientes como eso.

Si b no tiene efectos secundarios, aún se puede ejecutar en paralelo con a (para cualquier valor de "en paralelo", incluido el pipeline).

Si b tiene efectos secundarios que la arquitectura de la CPU no puede cancelar cuando la predicción de bifurcación falla, entonces sí, esto podría requerir demoras que no existirían si se evaluaran siempre ambos lados. Por lo tanto, es algo a tener en cuenta si alguna vez descubre que los operadores de cortocircuito están creando un cuello de botella de rendimiento en su código, pero no vale la pena preocuparse por lo contrario.

Pero el cortocircuito se usa para controlar el flujo tanto como para ahorrar trabajo innecesario. Es común entre los idiomas que he usado, por ejemplo, el idioma Perl:

open($filename) or die("couldn''t open file");

el modismo de shell:

do_something || echo "that failed"

o la expresión C / C ++ / Java / etc:

if ((obj != 0) && (obj->ready)) { do_something; } // not -> in Java of course.

En todos estos casos, necesita un cortocircuito, de modo que el RHS solo se evalúa si el LHS dicta que debería ser. ¡En tales casos no tiene sentido comparar el rendimiento con el código alternativo que está mal!