void* Worker::run() { for (int i = 0;; i++) { printf("thread %lu, loop %d - waiting for item...\n", (long unsigned int)self(), i); WorkItem* item = m_queue.remove(); printf("thread %lu, loop %d - got one item\n", (long unsigned int)self(), i); { int temps = 0, fdecoding = 0; // // ON CREE UN OBJET POUR LA MESURE DU TEMPS DE SIMULATION (REMISE A ZERO POUR CHAQUE Eb/N0) // CTimer temps_ecoule(true); CTimer term_refresh(true); CErrorAnalyzer errCounters(item->getData(), frameErrorLimit, false, false); CErrorAnalyzer errCounter (item->getData(), frameErrorLimit, true, true); // // ON CREE L'OBJET EN CHARGE DES INFORMATIONS DANS LE TERMINAL UTILISATEUR // CTerminal terminal(&errCounters, &temps_ecoule, item->getNoise()->getEb_N0()); // // ON GENERE LA PREMIERE TRAME BRUITEE // item->getNoise()->generate(); errCounter.store_enc_bits(); while( 1 ) { // // ON LANCE LE TRAITEMENT SUR PLUSIEURS THREAD... // CTimer essai(true); // decoder->decode( item->getData()->get_t_noise_data(), item->getData()->get_t_decode_data(), numberIter ); // temps += essai.get_time_ms(); fdecoding += 1; #pragma omp sections { #pragma omp section { // item->getNoise()->generate(); } #pragma omp section { // errCounter.generate(); } } // // ON COMPTE LE NOMBRE D'ERREURS DANS LA TRAME DECODE // // errCounters.reset_internals(); // errCounters.accumulate( &errCounter ); // // ON compares the frame error with the limits imposed by the user. // If it exceeds then displays the results on Eb / N0 current. // // if ( errCounters.fe_limit_achieved() == true ){ // break; // } // // AFFICHAGE A L'ECRAN DE L'EVOLUTION DE LA SIMULATION SI NECESSAIRE // // if( term_refresh.get_time_sec() >= 1 ){ // term_refresh.reset(); // terminal.temp_report(); // } // if( (simTotalTimer->get_time_sec() >= STOP_TIMER_SECOND) && (STOP_TIMER_SECOND != -1) ) // { // printf("(II) THE SIMULATION HAS STOP DUE TO THE (USER) TIME CONTRAINT.\n"); // printf("(II) PERFORMANCE EVALUATION WAS PERFORMED ON %d RUNS, TOTAL TIME = %dms\n", fdecoding, temps); // temps /= fdecoding; // printf("(II) + TIME / RUN = %dms\n", temps); // int workL = 4 * numberThreadOnGpu; // int kbits = workL * _N / temps ; // float mbits = ((float)kbits) / 1000.0; // printf("(II) + DECODER LATENCY (ms) = %d\n", temps); // printf("(II) + DECODER THROUGHPUT (Mbps)= %.1f\n", mbits); // printf("(II) + (%.2fdB, %dThd : %dCw, %dits) THROUGHPUT = %.1f\n", item->getNoise()->getEb_N0(), numberThreadOnGpu, workL, numberIter, mbits); // cout << endl << "Temps = " << temps << "ms : " << kbits; // cout << "kb/s : " << ((float)temps/numberThreadOnGpu) << "ms/frame" << endl << endl; // break; // } } // terminal.final_report(); } delete item; } return NULL; }
int main(int argc, char* argv[]) { int p; srand( 0 ); printf("(II) LDPC DECODER - Flooding scheduled decoder\n"); printf("(II) MANIPULATION DE DONNEES (IEEE-754 - %ld bits)\n", (long int)8*sizeof(int)); printf("(II) GENEREE : %s - %s\n", __DATE__, __TIME__); double Eb_N0; double MinSignalSurBruit = 0.50; double MaxSignalSurBruit = 3.01; double PasSignalSurBruit = 0.10; int NOMBRE_ITERATIONS = 20; int STOP_TIMER_SECOND = -1; bool QPSK_CHANNEL = false; bool Es_N0 = false; // FALSE => MODE Eb_N0 int NB_THREAD_ON_GPU = 1024;; int FRAME_ERROR_LIMIT = 200; char defDecoder[] = "fMS"; const char* type = defDecoder; cudaSetDevice(0); cudaDeviceSynchronize(); cudaThreadSynchronize(); // // ON VA PARSER LES ARGUMENTS DE LIGNE DE COMMANDE // for (p=1; p<argc; p++) { if( strcmp(argv[p], "-min") == 0 ){ MinSignalSurBruit = atof( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-max") == 0 ){ MaxSignalSurBruit = atof( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-pas") == 0 ){ PasSignalSurBruit = atof( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-timer") == 0 ){ STOP_TIMER_SECOND = atoi( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-iter") == 0 ){ NOMBRE_ITERATIONS = atoi( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-fer") == 0 ){ FRAME_ERROR_LIMIT = atoi( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-qef") == 0 ){ BER_SIMULATION_LIMIT = true; BIT_ERROR_LIMIT = ( atof( argv[p+1] ) ); p += 1; }else if( strcmp(argv[p], "-bpsk") == 0 ){ QPSK_CHANNEL = false; }else if( strcmp(argv[p], "-qpsk") == 0 ){ QPSK_CHANNEL = true; }else if( strcmp(argv[p], "-Eb/N0") == 0 ){ Es_N0 = false; }else if( strcmp(argv[p], "-Es/N0") == 0 ){ Es_N0 = true; }else if( strcmp(argv[p], "-n") == 0 ){ NB_THREAD_ON_GPU = atoi( argv[p+1] ); p += 1; }else if( strcmp(argv[p], "-fMS") == 0 ){ type = "fMS"; }else if( strcmp(argv[p], "-xMS") == 0 ){ type = "xMS"; }else if( strcmp(argv[p], "-MS") == 0 ){ type = "MS"; }else if( strcmp(argv[p], "-OMS") == 0 ){ type = "OMS"; }else if( strcmp(argv[p], "-NMS") == 0 ){ type = "NMS"; }else if( strcmp(argv[p], "-2NMS") == 0 ){ type = "2NMS"; }else if( strcmp(argv[p], "-info") == 0 ){ show_info(); exit( 0 ); }else{ printf("(EE) Unknown argument (%d) => [%s]\n", p, argv[p]); exit(0); } } double rendement = (double)(NmoinsK)/(double)(_N); printf("(II) Code LDPC (N, K) : (%d,%d)\n", _N, _K); printf("(II) Rendement du code : %.3f\n", rendement); printf("(II) # ITERATIONs du CODE : %d\n", NOMBRE_ITERATIONS); printf("(II) FER LIMIT FOR SIMU : %d\n", FRAME_ERROR_LIMIT); printf("(II) SIMULATION RANGE : [%.2f, %.2f], STEP = %.2f\n", MinSignalSurBruit, MaxSignalSurBruit, PasSignalSurBruit); printf("(II) MODE EVALUATION : %s\n", ((Es_N0)?"Es/N0":"Eb/N0") ); printf("(II) MIN-SUM ALGORITHM : %s\n", type ); printf("(II) FAST STOP MODE : %d\n", QUICK_STOP); CTimer simu_timer(true); // // ON CREE AUTANT DE TRAMES QUE L'ON A DE THREADS // CTrame simu_data(_N, _K, NB_THREAD_ON_GPU); CGPUDecoder* decoder; if( strcmp(type, "fMS") == 0 ){ decoder = new CGPU_Decoder_MS_SIMD( NB_THREAD_ON_GPU, _N, _K, _M ); }else if( strcmp(type, "MS") == 0 ){ decoder = new CGPU_Decoder_MS_SIMD( NB_THREAD_ON_GPU, _N, _K, _M ); }else if( strcmp(type, "OMS") == 0 ){ decoder = new CGPU_Decoder_OMS_SIMD( NB_THREAD_ON_GPU, _N, _K, _M ); }else if( strcmp(type, "NMS") == 0 ){ decoder = new CGPU_Decoder_NMS_SIMD( NB_THREAD_ON_GPU, _N, _K, _M ); }else if( strcmp(type, "2NMS") == 0 ){ decoder = new CGPU_Decoder_2NMS_SIMD( NB_THREAD_ON_GPU, _N, _K, _M ); }else if( strcmp(type, "xMS") == 0 ){ decoder = new CGPU_Decoder_MS_SIMD_v2( NB_THREAD_ON_GPU, _N, _K, _M ); }else{ printf("(EE) Requested decoder does not exist !\n"); exit( 0 ); } decoder->initialize(); CChanel_AWGN_SIMD noise(&simu_data, 4, QPSK_CHANNEL, Es_N0); Eb_N0 = MinSignalSurBruit; int temps = 0, fdecoding = 0; while (Eb_N0 <= MaxSignalSurBruit){ // // ON CREE UN OBJET POUR LA MESURE DU TEMPS DE SIMULATION (REMISE A ZERO POUR CHAQUE Eb/N0) // CTimer temps_ecoule(true); CTimer term_refresh(true); noise.configure( Eb_N0 ); CErrorAnalyzer errCounters(&simu_data, FRAME_ERROR_LIMIT, false, false); CErrorAnalyzer errCounter (&simu_data, FRAME_ERROR_LIMIT, true, true); // // ON CREE L'OBJET EN CHARGE DES INFORMATIONS DANS LE TERMINAL UTILISATEUR // CTerminal terminal(&errCounters, &temps_ecoule, Eb_N0); // // ON GENERE LA PREMIERE TRAME BRUITEE // noise.generate(); errCounter.store_enc_bits(); while( 1 ){ // // ON LANCE LE TRAITEMENT SUR PLUSIEURS THREAD... // CTimer essai(true); decoder->decode( simu_data.get_t_noise_data(), simu_data.get_t_decode_data(), NOMBRE_ITERATIONS ); temps += essai.get_time_ms(); fdecoding += 1; #pragma omp sections { #pragma omp section { noise.generate(); } #pragma omp section { errCounter.generate(); } } // // ON COMPTE LE NOMBRE D'ERREURS DANS LA TRAME DECODE // errCounters.reset_internals(); errCounters.accumulate( &errCounter ); // // ON compare le Frame Error avec la limite imposee par l'utilisateur. Si on depasse // alors on affiche les resultats sur Eb/N0 courant. // if ( errCounters.fe_limit_achieved() == true ){ break; } // // AFFICHAGE A L'ECRAN DE L'EVOLUTION DE LA SIMULATION SI NECESSAIRE // if( term_refresh.get_time_sec() >= 1 ){ term_refresh.reset(); terminal.temp_report(); } if( (simu_timer.get_time_sec() >= STOP_TIMER_SECOND) && (STOP_TIMER_SECOND != -1) ){ printf("(II) THE SIMULATION HAS STOP DUE TO THE (USER) TIME CONTRAINT.\n"); printf("(II) PERFORMANCE EVALUATION WAS PERFORMED ON %d RUNS, TOTAL TIME = %dms\n", fdecoding, temps); temps /= fdecoding; printf("(II) + TIME / RUN = %dms\n", temps); int workL = 4 * NB_THREAD_ON_GPU; int kbits = workL * _N / temps ; float mbits = ((float)kbits) / 1000.0; printf("(II) + DECODER LATENCY (ms) = %d\n", temps); printf("(II) + DECODER THROUGHPUT (Mbps)= %.1f\n", mbits); printf("(II) + (%.2fdB, %dThd : %dCw, %dits) THROUGHPUT = %.1f\n", Eb_N0, NB_THREAD_ON_GPU, workL, NOMBRE_ITERATIONS, mbits); cout << endl << "Temps = " << temps << "ms : " << kbits; cout << "kb/s : " << ((float)temps/NB_THREAD_ON_GPU) << "ms/frame" << endl << endl; break; } } terminal.final_report(); if( (simu_timer.get_time_sec() >= STOP_TIMER_SECOND) && (STOP_TIMER_SECOND != -1) ){ break; } Eb_N0 = Eb_N0 + PasSignalSurBruit; if( BER_SIMULATION_LIMIT == true ){ if( errCounters.ber_value() < BIT_ERROR_LIMIT ){ printf("(II) THE SIMULATION HAS STOP DUE TO THE (USER) QUASI-ERROR FREE CONTRAINT.\n"); break; } } } //printf("(II) Simulation is now terminated !\n"); //delete decoder; //printf("(II) Simulation is now terminated !\n"); return 0; }