¿Por qué la necesidad de reducir std :: conmutabilidad

votos
5

https://en.cppreference.com/w/cpp/algorithm/reduce

Se dice que el comportamiento de una operación no está definido si la operación no es conmutativa, pero ¿por qué? Acabamos de dividir la matriz en bloques y luego fusionar el resultado, es sólo necesario asociatividad?

Publicado el 13/02/2020 a las 23:51
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
1

El comportamiento es en realidad no determinista si la operación entre los operandos no es conmutativa. "no determinista" no es lo mismo que "indefinido". Punto flotante matemáticas no es conmutativa, por ejemplo. Esta es una de las razones por las que una llamada a std::reduceno ser determinista, ya que la función binaria se aplica en un orden especificado.

Se refieren a esta nota en la norma:

Nota: La diferencia entre reducey accumulatees que reducir aplica binary_open un orden especificado, lo que produce un resultado determinista para binary_op no asociativo o no conmutativo tal como la adición de coma flotante. -Fin nota]

Respondida el 14/02/2020 a las 00:02
fuente por usuario

votos
1

El estándar define la suma generalizar como sigue: numeric.defns

Definir GENERALIZED_NONCOMMUTATIVE_SUM (op, a1, ..., an) de la siguiente manera:

  • a1 cuando N es 1, de lo contrario

  • op (GENERALIZED_NONCOMMUTATIVE_SUM (op, a1, ..., ak), OP (GENERALIZED_NONCOMMUTATIVE_SUM (op, AM, ..., an)) para cualquier K, donde 1

Definir GENERALIZED_SUM (op, a1, ..., an) como GENERALIZED_NONCOMMUTATIVE_SUM (op, B1, ..., Bn), donde b1, ..., Bn puede ser cualquier permutación de a1, ..., an.

Por lo tanto, el orden de adición, así como el orden de los operandos es no especificado. Así que si la operación binaria no es conmutativo o no asociativo, el resultado es indeterminado.

Esto también se dijo explícitamente aquí .

En cuanto a por qué: Da la biblioteca de los proveedores más libertad, por lo que pueden o no pueden ponerlo en práctica mejor. Como un ejemplo donde la aplicación se puede beneficiar de conmutatividad. Considere la suma a+b+c+d+e, primero calculamos a+by c+den paralelo. Ahora a+bregresa antes c+dhace (como puede suceder, ya que se hace en paralelo). En lugar de esperar a que el valor de retorno de la c+dque ahora puede calcular directamente (a+b)+ey luego agregar este resultado con el resultado de c+d. Así que al final, hemos calculado ((a+b)+e)+(c+d), que es un reordenamiento de a+b+c+d+e.

Respondida el 14/02/2020 a las 00:07
fuente por usuario

votos
6

std::reducerequiere tanto la asociatividad y conmutatividad. La asociatividad es claramente necesaria para un algoritmo paralelo, ya que desea realizar el cálculo en trozos separados y luego combinarlos.

En cuanto a la propiedad conmutativa: De acuerdo con una publicación de Reddit por MSVC desarrollador STL Billy O'Neal, esto es necesario para permitir la vectorización con las instrucciones SIMD:

Conmutatividad también es necesaria para que la vectorización, ya que el código que desea para reducir al salir como algo así como:

vecRegister = load_contiguous(first);
while (a vector register sized chunk is left) {
    first += packSize;
    vecRegister = add_packed(load_contiguous(first), vecRegister);
}
// combine vecRegister's packed components

etc., que ints dadas y registros SSE y a * b * c * d * e * f * g * h da algo así como (a * e) * (b * f) * (c * g) * (d * h ).

La mayoría de los otros idiomas no están haciendo las cosas explícitas para hacer la vectorización de su reducción posible. Y nada dice que no podemos añadir un noncommutative_reduce o algo así en el futuro si alguien viene con un caso de uso convincente.

Respondida el 14/02/2020 a las 00:13
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more