2015-08-26 16 views
10

Sto cercando di confrontare le prestazioni di std::sort (utilizzando std::vector di structs) vs intel ipp sort.std :: sort vs intel ipp sort performance. Che cosa sto facendo di sbagliato?

Sto facendo funzionare questo test su un processore Intel Xeon model name : Intel(R) Xeon(R) CPU X5670 @ 2.93GHz

sto classificare un vettore di lunghezza 20000 elementi e smistamento 200 volte. Ho provato 2 differenti di routine di ordinamento ipp. ippsSortDescend_64f_I e ippsSortRadixDescend_64f_I. In tutti i casi, l'ordinamento ipp era almeno da 5 a 10 volte più lento di std::sort. Mi aspettavo che l'ordinamento ipp fosse più lento per gli array più piccoli, ma in caso contrario dovrebbe essere generalmente più veloce di std::sort. Mi sto perdendo qualcosa qui? Che cosa sto facendo di sbagliato?

std::sort è sempre più veloce in tutti i miei casi di test.

Ecco il mio programma

#include <array> 
#include <iostream> 
#include <algorithm> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/time.h> 
#include <sys/timeb.h> 

#include <vector> 
#include <chrono> 

#include "ipp.h" 

using namespace std; 

const int SIZE = 2000000; 
const int ITERS = 200; 

//Chrono typedefs 
typedef std::chrono::high_resolution_clock Clock; 
typedef std::chrono::microseconds microseconds; 

//////////////////////////////////// std /////////////////////////////////// 

typedef vector<double> myList; 

void initialize(myList & l, Ipp64f* ptr) 
{ 
    double randomNum; 
    for (int i = 0; i < SIZE; i++) 
    { 
     randomNum = 1.0 * rand()/(RAND_MAX/2) - 1; 
     l.push_back(randomNum); 
     ptr[i] = randomNum; 
    } 
} 


void test_sort() 
{ 
     array<myList, ITERS> list; 
     array<Ipp64f*, ITERS> ippList; 

     // allocate 
     for(int i=0; i<ITERS;i++) 
     { 
       list[i].reserve(SIZE); 
       ippList[i] = ippsMalloc_64f(SIZE); 
     } 

     // initialize 
     for(int i=0;i<ITERS;i++) 
     { 
       initialize(list[i], ippList[i]); 
     } 

     cout << "\n\nTest Case 1: std::sort\n"; 
     cout << "========================\n"; 

     // sort vector 
     Clock::time_point t0 = Clock::now(); 
     for(int i=0; i<ITERS;i++) 
     { 
      std::sort(list[i].begin(), list[i].end()); 
     } 
     Clock::time_point t1 = Clock::now(); 
     microseconds ms = std::chrono::duration_cast<microseconds>(t1 - t0); 
     std::cout << ms.count() << " micros" << std::endl; 

     ////////////////////////////////// IPP //////////////////////////////////////// 

     cout << "\n\nTest Case 2: ipp::sort\n"; 
     cout << "========================\n"; 

     // sort ipp 
     Clock::time_point t2 = Clock::now(); 
     for(int i=0; i<ITERS;i++) 
     { 
       ippsSortAscend_64f_I(ippList[i], SIZE); 
     } 
     Clock::time_point t3 = Clock::now(); 
     microseconds ms1 = std::chrono::duration_cast<microseconds>(t3 - t2); 
     std::cout << ms1.count() << " micros" << std::endl; 

     for(int i=0; i<ITERS;i++) 
     { 
      ippsFree(ippList[i]); 
     } 
} 


/////////////////////////////////////////////////////////////////////////////////////// 

int main() 
{ 
    srand (time(NULL)); 

    cout << "Test for sorting an array of structures.\n" << endl; 
    cout << "Test case: \nSort an array of structs ("<<ITERS<<" iterations) with double of length "<<SIZE<<". \n"; 
     IppStatus status=ippInit(); 
     test_sort(); 
    return 0; 
} 

///////////////////////////////////////////////////////////////////////////// 

comando compilazione è: uscita

/share/intel/bin/icc -O2 -I$(IPPROOT)/include sorting.cpp -lrt -L$(IPPROOT)/lib/intel64 -lippi -lipps -lippvm -lippcore -std=c++0x  

Programma:

Test for sorting an array of structures. 

Test case: 
Sort an array of structs (200 iterations) with double of length 2000000. 


Test Case 1: std::sort 
======================== 
38117024 micros 


Test Case 2: ipp::sort 
======================== 
48917686 micros 
+1

Si noti che non si esegue solo il benchmark dell'ordinamento, ma anche la randomizzazione dei vettori. Ti consiglio di misurare solo l'ordinamento effettivo, molte volte aggiungendo le ore insieme per ottenere un tempo totale, quindi mostra il tempo totale e il tempo medio. –

+0

lo proverò ora, ma solo per il test ho provato rimuovendo le funzioni 'randomize' in modo che solo il primo ciclo abbia un vettore casuale dove altre iterazioni hanno vettori ordinati. In questo caso anche 'std :: sort' era molto più veloce di' ipp'. comunque, controllando aggiungendo ora il tempo. – Alok

+1

@usr: il confronto non dovrebbe restituire un numero negativo o alcun numero. Dovrebbe restituire un bool. Vero se il primo argomento dovrebbe precedere il secondo e falso altrimenti. –

risposta

1

per risultato più preciso è necessario

  • confrontare l'ordinamento di esattamente le stesse distribuzioni di numeri casuali;
  • rimuovere randomize dalla temporizzazione;
  • usa le funzioni ippsSort * 32f, per ordinare 'float' (non 'double') nel caso IPP.
+0

Ho apportato le modifiche come suggerito. sto usando 'ippsSortDescend_64f_I' e ho cambiato tutti i' float' in 'double'. Vedo ancora che ipp sort è molto più lento rispetto a 'std :: sort'. Sto iniziando a credere che 'std :: sort' sia più efficiente di' ipp'. – Alok

-1

Credo che ti sei dimenticato di chiamare ippInit() prima le MISURE

+0

è fatto nel principale. – Alok

4

ho eseguire il codice sul mio computer (Core i7 860).

std::sort 32,763,268 (~33s) 

ippsSortAscend_64f_I 34,217,517 (~34s) 

ippsSortRadixAscend_64f_I 15,319,053 (~15s) 

Questi sono i risultati previsti. std :: sort è in linea e altamente ottimizzato, mentre ippsSort_ * ha overhead di chiamata alla funzione e molti controlli interni eseguiti da tutte le funzioni ipp. Questo dovrebbe spiegare il piccolo rallentamento per la funzione ippsSortAscend. Ordinamento Radix è ancora due volte più veloce come previsto, dal momento che non è un ordinamento basato sul confronto.

Problemi correlati