2010-10-10 13 views
14

En referencia a fastest sort of fixed length 6 int array, no entiendo completamente cómo este sorting network supera un algoritmo como insertion sort.¿Cómo una red de clasificación vence a los algoritmos de clasificación genéricos?

Formulario esa pregunta, he aquí una comparación del número de ciclos de CPU necesario para completar el tipo:

Linux de 32 bits, GCC 4.4.1, procesador Intel Core 2 Quad Q8300, O2

  • ordenación por inserción (Daniel Stutzbach): 1425
  • redes de ordenación (Daniel Stutzbach): 1080

El código utilizado es el siguiente:

ordenación por inserción (Daniel Stutzbach)

static inline void sort6_insertion_sort_v2(int *d){ 
    int i, j; 
    for (i = 1; i < 6; i++) { 
      int tmp = d[i]; 
      for (j = i; j >= 1 && tmp < d[j-1]; j--) 
        d[j] = d[j-1]; 
      d[j] = tmp; 
    } 
} 

redes de ordenación (Daniel Stutzbach)

static inline void sort6_sorting_network_v1(int * d){ 
#define SWAP(x,y) if (d[y] < d[x]) { int tmp = d[x]; d[x] = d[y]; d[y] = tmp; } 
    SWAP(1, 2); 
    SWAP(0, 2); 
    SWAP(0, 1); 
    SWAP(4, 5); 
    SWAP(3, 5); 
    SWAP(3, 4); 
    SWAP(0, 3); 
    SWAP(1, 4); 
    SWAP(2, 5); 
    SWAP(2, 4); 
    SWAP(1, 3); 
    SWAP(2, 3); 
#undef SWAP 
} 

I entender d que las redes de clasificación son realmente buenas para ordenar en paralelo, porque algunos de los pasos son independientes de los otros pasos. Pero aquí no estamos usando la paralelización.

Espero que sea más rápido, ya que tiene la ventaja de conocer el número exacto de elementos de antemano. ¿Dónde y por qué exactamente el ordenamiento por inserción hace comparaciones innecesarias?

EDIT1:

Este es el conjunto de entrada de estos códigos se comparan con:

int d[6][6] = {\ 
    {1, 2, 3, 4, 5, 6},\ 
    {6, 5, 4, 3, 2, 1},\ 
    {100, 2, 300, 4, 500, 6},\ 
    {100, 2, 3, 4, 500, 6},\ 
    {1, 200, 3, 4, 5, 600},\ 
    {1, 1, 2, 1, 2, 1}\ 
};\ 
+0

¿El orden de la matriz de entrada es aleatorio aquí? ¿O estás usando una matriz descendente? –

+0

@crypto: pregunta actualizada! – Lazer

Respuesta

19

Pero aquí no estamos utilizando la paralelización.

Las CPU modernas pueden determinar cuándo las instrucciones son independientes y las ejecutarán en paralelo. Por lo tanto, aunque solo haya un hilo, se puede aprovechar el paralelismo de la red de clasificación.

¿Dónde exactamente inserta ordenación hace comparaciones innecesarias?

La manera más fácil de ver las comparaciones adicionales es hacer un ejemplo a mano.

Insertion sort: 
6 5 4 3 2 1 
5 6 4 3 2 1 
5 4 6 3 2 1 
4 5 6 3 2 1 
4 5 3 6 2 1 
4 3 5 6 2 1 
3 4 5 6 2 1 
3 4 5 2 6 1 
3 4 2 5 6 1 
3 2 4 5 6 1 
2 3 4 5 6 1 
2 3 4 5 1 6 
2 3 4 1 5 6 
2 3 1 4 5 6 
2 1 3 4 5 6 
1 2 3 4 5 6 

Sorting network: 
6 5 4 3 2 1 
6 4 5 3 2 1 
5 4 6 3 2 1 
4 5 6 3 2 1 # These three can execute in parallel with the first three 
4 5 6 3 1 2 # 
4 5 6 2 1 3 # 
4 5 6 1 2 3 
1 5 6 4 2 3 
1 2 6 4 5 3 
1 2 3 4 5 6 
1 2 3 4 5 6 
+1

@Daniel: Bien, ya que estos caminos son completamente diferentes, no podemos compararlos directamente. Ciertamente, la red de clasificación nos permite ordenar en menor cantidad de comparaciones. Para expresar mi pregunta de una manera diferente, ** ¿qué nos impide optimizar la ordenación por inserción para usar esta secuencia de swaps para cualquier cantidad de entradas? ** – Lazer

+0

Lazer: me temo que no entiendo. ¿A qué secuencia te refieres cuando dices "esta secuencia de intercambios"? Además, ¿quiso decir "optimizar el tipo de inserción" o tenía la intención de referirse a las redes de clasificación? –

+2

@Daniel: Lo siento por falta de claridad. En otros términos, ¿por qué utilizamos la ordenación por inserción si las redes de clasificación son más * eficientes *? – Lazer

1

creo que loop unwinding es lo que causa los resultados más rápidos en el algoritmo de red tipo

0

Teóricamente, el código podría ser aproximadamente el mismo si el compilador pudiera desenrollar por completo los bucles en el Tipo de inserción. El primer bucle se puede desenrollar fácilmente, mientras que el segundo no se puede desenrollar tan fácil.

También puede darse el caso de que, debido a que el código no es tan simple como el código de clasificación de red, el compilador puede realizar menos optimizaciones. Creo que hay más dependencias en el género de inserción que en el ordenamiento de red, lo que puede marcar una gran diferencia cuando el compilador intenta optimizar el código (corrígeme si estoy equivocado).

0

creo que todos ustedes preguntas son respondidas en Daniel Stutzbach respuesta al mensaje original:

El algoritmo informados es similar a un tipo de inserción, pero parece que ha minimizado el número de swaps a costa de más comparaciones. Las comparaciones son mucho más caras que las permutas, porque las ramificaciones pueden hacer que la tubería de instrucciones se bloquee en .

+0

No puede hacer esa generalización.Si sus objetos de datos son grandes, pero la extracción y comparación de la clave es rápida, las comparaciones son mucho más económicas que los intercambios. Supongo que la única vez que los swaps son más baratos es cuando sus elementos de datos son de un tipo simple. –

1

Creo que la cantidad de 'trabajo' hecho en un algoritmo paralelo y un algoritmo de serie es casi lo mismo. Solo que dado que el trabajo se distribuye, obtendrías resultados más rápidos. Creo que obtendrá un resultado convincentemente más rápido en caso de que el tamaño de la entrada sea suficiente para justificar el uso de un algoritmo paralelo.

En caso de inserción, la división de ordenación entre los procesadores es tal que forma una tubería, y llevaría algún tiempo llenar la tubería y luego produciría beneficios del algoritmo paralelo.

4

La mejor pregunta es por qué la red de clasificación solo supera al tipo de inserción (generalmente un tipo muy lento) en ~ 50%. La respuesta es que big-O no es tan importante cuando n es muy pequeño. En cuanto a la pregunta de OP, Daniel tiene la mejor respuesta.

+0

¡sigue siendo importante! cuando tienes 1000000 de tipos pequeños, incluso una pequeña diferencia haría un cambio. –

+1

@DenRoman: Big-O no es lo importante cuando tienes 1000000 minúsculos géneros. Por el contrario, el factor constante es lo importante en este caso. –

Cuestiones relacionadas