Exemplo n.º 1
0
 ListNode* recursive_merge(vector<ListNode*>& lists, int left, int right) {
     if (left < right) {
         int mid = (left+right)/2;
         ListNode* l = recursive_merge(lists, left, mid);
         ListNode* r = recursive_merge(lists, mid+1, right);
         return merge(l, r);
     } else {
         return lists[left];
     }
 }
Exemplo n.º 2
0
int main(int argc, char ** argv)
{
    int i;
    int ret;
    int hw_threads;
    int sw_threads;
    int running_threads;
    int buffer_size;
    int slice_size;
    unsigned int *data, *copy;

    timing_t t_start, t_stop;
    ms_t t_generate;
    ms_t t_sort;
    ms_t t_merge;
    ms_t t_check;

    if ((argc < 4) || (argc > 4))
    {
        print_help();
        exit(1);
    }
    // we have exactly 3 arguments now...
    hw_threads = atoi(argv[1]);
    sw_threads = atoi(argv[2]);

    // Base unit is bytes. Use macros TO_WORDS, TO_PAGES and TO_BLOCKS for conversion.
    buffer_size = atoi(argv[3])*PAGE_SIZE*PAGES_PER_THREAD;
    slice_size  = PAGE_SIZE*PAGES_PER_THREAD;

    running_threads = hw_threads + sw_threads;

    //int gettimeofday(struct timeval *tv, struct timezone *tz);

    // init mailboxes
    mbox_init(&mb_start,TO_BLOCKS(buffer_size));
    mbox_init(&mb_stop ,TO_BLOCKS(buffer_size));

    // init reconos and communication resources
    reconos_init(14,15);

    res[0].type = RECONOS_TYPE_MBOX;
    res[0].ptr  = &mb_start;
    res[1].type = RECONOS_TYPE_MBOX;
    res[1].ptr  = &mb_stop;

    printf("Creating %i hw-threads: ", hw_threads);
    fflush(stdout);
    for (i = 0; i < hw_threads; i++)
    {
        printf(" %i",i);
        fflush(stdout);
        reconos_hwt_setresources(&(hwt[i]),res,2);
        reconos_hwt_create(&(hwt[i]),i,NULL);
    }
    printf("\n");

    // init software threads
    printf("Creating %i sw-threads: ",sw_threads);
    fflush(stdout);
    for (i = 0; i < sw_threads; i++)
    {
        printf(" %i",i);
        fflush(stdout);
        pthread_attr_init(&swt_attr[i]);
        pthread_create(&swt[i], &swt_attr[i], sort_thread, (void*)res);
    }
    printf("\n");


    //print_mmu_stats();

    // create pages and generate data
    t_start = gettime();

    printf("malloc page aligned ...\n");
    data = malloc_page_aligned(TO_PAGES(buffer_size));
    copy = malloc_page_aligned(TO_PAGES(buffer_size));
    printf("generate data ...\n");
    generate_data( data, TO_WORDS(buffer_size));
    memcpy(copy,data,TO_WORDS(buffer_size)*4);

    t_stop = gettime();
    t_generate = calc_timediff_ms(t_start,t_stop);

    // print data of first page
    printf("Printing of generated data skipped. \n");
    //print_data(data, TO_WORDS(buffer_size));


    // Start sort threads
    t_start = gettime();

    printf("Putting %i blocks into job queue: ", TO_BLOCKS(buffer_size));
    fflush(stdout);
    for (i=0; i<TO_BLOCKS(buffer_size); i++)
    {
        printf(" %i",i);
        fflush(stdout);
        mbox_put(&mb_start,(unsigned int)data+(i*BLOCK_SIZE));
    }
    printf("\n");

    // Wait for results
    printf("Waiting for %i acknowledgements: ", TO_BLOCKS(buffer_size));
    fflush(stdout);
    for (i=0; i<TO_BLOCKS(buffer_size); i++)
    {
        printf(" %i",i);
        fflush(stdout);
        ret = mbox_get(&mb_stop);
    }
    printf("\n");

    t_stop = gettime();
    t_sort = calc_timediff_ms(t_start,t_stop);


    // merge data
    t_start = gettime();

    printf("Merging sorted data slices...\n");
    unsigned int * temp = malloc_page_aligned(TO_PAGES(buffer_size));
    //printf("Data buffer at address %p \n", (void*)data);
    //printf("Address of temporary merge buffer: %p\n", (void*)temp);
    //printf("Total size of data in bytes: %i\n",buffer_size);
    //printf("Size of a sorting block in bytes: %i\n",BLOCK_SIZE);
    data = recursive_merge( data,
                            temp,
                            TO_WORDS(buffer_size),
                            TO_WORDS(BLOCK_SIZE),
                            simple_merge
                          );

    t_stop = gettime();
    t_merge = calc_timediff_ms(t_start,t_stop);

    // check data
    //data[0] = 6666; // manual fault
    t_start = gettime();

    printf("Checking sorted data: ... ");
    fflush(stdout);
    ret = check_data( data, copy, TO_WORDS(buffer_size));
    if (ret >= 0)
    {
        printf("failure at word index %i\n", -ret);
        printf("expected 0x%08X    found 0x%08X\n",copy[ret],data[ret]);
        printf("dumping the first 2048 words:\n");
        for(i = 0; i < 2048; i++) {
            printf("%08X ",data[i]);
            if((i % 8) == 7) printf("\n");
        }
    }
    else
    {
        printf("success\n");
        //print_data(data, TO_WORDS(buffer_size));
    }

    t_stop = gettime();
    t_check = calc_timediff_ms(t_start,t_stop);

    // terminate all threads
    printf("Sending terminate message to %i threads:", running_threads);
    fflush(stdout);
    for (i=0; i<running_threads; i++)
    {
        printf(" %i",i);
        fflush(stdout);
        mbox_put(&mb_start,UINT_MAX);
    }
    printf("\n");

    printf("Waiting for termination...\n");
    for (i=0; i<hw_threads; i++)
    {
        pthread_join(hwt[i].delegate,NULL);
    }
    for (i=0; i<sw_threads; i++)
    {
        pthread_join(swt[i],NULL);
    }

    printf("\n");
    print_mmu_stats();
    printf( "Running times (size: %d words, %d hw-threads, %d sw-threads):\n"
            "\tGenerate data: %lu ms\n"
            "\tSort data    : %lu ms\n"
            "\tMerge data   : %lu ms\n"
            "\tCheck data   : %lu ms\n"
            "Total computation time (sort & merge): %lu ms\n",
            TO_WORDS(buffer_size), hw_threads, sw_threads,
            t_generate, t_sort, t_merge, t_check, t_sort + t_merge );


    //free(data);
    // Memory Leak on variable data!!!

    return 0;
}
Exemplo n.º 3
0
int main( int argc, char *argv[] )
{

    unsigned int i, start_count = 0, done_count = 0;
    timing_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge =
        0, t_check = 0;
    unsigned int *addr;
    unsigned int dummy;
    int retval;

    printf( "-------------------------------------------------------\n"
            "ReconOS hardware multithreading case study (sort)\n"
            "(c) Computer Engineering Group, University of Paderborn\n\n"
            "eCos/POSIX, multi-threaded hardware version (" __FILE__ ")\n"
            "Compiled on " __DATE__ ", " __TIME__ ".\n"
            "-------------------------------------------------------\n\n" );

#ifdef USE_CACHE
    printf( "enabling data cache for external ram\n" );
    XCache_EnableDCache( 0x80000000 );
#else
    printf( "data cache disabled\n" );
    XCache_DisableDCache(  );
#endif

    data = buf_a;

    //----------------------------------
    //-- GENERATE DATA
    //----------------------------------
    printf( "Generating data..." );
    t_start = gettime(  );
    generate_data( data, SIZE );
    t_stop = gettime(  );
    t_gen = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

#ifdef USE_CACHE
    // flush cache contents - the hardware can only read from main memory
    // TODO: storing could be more efficient
    printf( "Flushing cache..." );
    XCache_EnableDCache( 0x80000000 );
    printf( "done\n" );
#endif

    //----------------------------------
    //-- SORT DATA
    //----------------------------------
    // create mail boxes for 'start' and 'complete' messages
    mb_start_attr.mq_flags   = mb_done_attr.mq_flags   = 0;
    mb_start_attr.mq_maxmsg  = mb_done_attr.mq_maxmsg  = 10;
    mb_start_attr.mq_msgsize = mb_done_attr.mq_msgsize = 4;
    mb_start_attr.mq_curmsgs = mb_done_attr.mq_curmsgs = 0;

    // unlink mailboxes, if they exist
    retval = mq_unlink("/mb_start");
    if (retval != 0 && errno != ENOENT) {    // we don't care if it doesn't exist
        diag_printf("unable to unlink mb_start");
    }
    retval = mq_unlink("/mb_done");
    if (retval != 0 && errno != ENOENT) {    // we don't care if it doesn't exist
        diag_printf("unable to unlink mb_done");
    }

    // open/create mailboxes
    mb_start = mq_open("/mb_start",
            O_RDWR | O_CREAT, S_IRWXU | S_IRWXG,
            &mb_start_attr);
    if (mb_start == (mqd_t)-1) {
        diag_printf("unable to create mb_start");
    }
    mb_done = mq_open("/mb_done",
            O_RDWR | O_CREAT, S_IRWXU | S_IRWXG,
            &mb_done_attr);
    if (mb_done == (mqd_t)-1) {
        diag_printf("unable to create mb_done");
    }

    // create sorting sowftware threads
    for ( i = 0; i < MT_HW_NUM_SW_THREADS; i++ ) {
        pthread_attr_init(&thread_sorter_attr[i]);
        pthread_create(&thread_sorter[i],
                &thread_sorter_attr[i],
                sort8k_entry_posix, (void*)i);
    }

    // create sorting hardware thread
    pthread_attr_init(&hwthread_sorter_attr);
    pthread_attr_setstacksize(&hwthread_sorter_attr, STACK_SIZE);
    rthread_attr_init(&hwthread_sorter_hwattr);
    rthread_attr_setslotnum(&hwthread_sorter_hwattr, 0);
    rthread_attr_setresources(&hwthread_sorter_hwattr, hwthread_sorter_resources, 2);
    rthread_create(&hwthread_sorter, &hwthread_sorter_attr, &hwthread_sorter_hwattr, (void*)0);

    printf( "Sorting data..." );
    i = 0;

    t_start = gettime(  );

    // put 9 messages into mb_start
    while ( start_count < 9 ) {
        addr = &data[i];
        if ( mq_send( mb_start, ( void * ) &addr, sizeof(addr), 0 ) == 0 ) {
            start_count++;
            i += N;
        } else {                                                          
            perror("while sending to mq_send");
            break;
        }
    }

    t_stop = gettime(  );
    t_sort += calc_timediff_ms( t_start, t_stop );

    while ( done_count < SIZE / N ) {
        t_start = gettime(  );
        // if we have something to distribute,
        // put one into the start mailbox
        if ( start_count < SIZE / N ) {
            addr = &data[i];
            if ( mq_send( mb_start, ( void * ) &addr, sizeof(addr), 0 ) == 0 ) {
                start_count++;
                i += N;
            } else {                                                          
                perror("while sending to mq_send");
                break;
            }
        }
        // see whether anybody's done
        if ( mq_receive( mb_done, (void*)&dummy, sizeof(dummy), 0 ) == sizeof(dummy) ) {
            done_count++;
        } else {
            perror( "while receiving from mq_done" );
            break;
        }
        t_stop = gettime(  );
        t_sort += calc_timediff_ms( t_start, t_stop );
    }
    printf( "done\n" );

#ifdef USE_CACHE
    // flush cache contents
    // TODO: invalidating would suffice
    printf( "Flushing cache..." );
    XCache_EnableDCache( 0x80000000 );
    printf( "done\n" );
#endif


    //----------------------------------
    //-- MERGE DATA
    //----------------------------------
    printf( "Merging data..." );
    t_start = gettime(  );
    data = recursive_merge( data, buf_b, SIZE, N, simple_merge );
    t_stop = gettime(  );
    t_merge = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- CHECK DATA
    //----------------------------------
    printf( "Checking sorted data..." );
    t_start = gettime(  );
    if ( check_data( data, SIZE ) != 0 )
        printf( "CHECK FAILED!\n" );
    else
        printf( "check successful.\n" );
    t_stop = gettime(  );
    t_check = calc_timediff_ms( t_start, t_stop );

    printf( "\nRunning times (size: %d words):\n"
            "\tGenerate data: %d ms\n"
            "\tSort data    : %d ms\n"
            "\tMerge data   : %d ms\n"
            "\tCheck data   : %d ms\n"
            "\nTotal computation time (sort & merge): %d ms\n",
            SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge );


    return 0;

}
Exemplo n.º 4
0
 ListNode* mergeKLists(vector<ListNode*>& givenLists) {
     if (givenLists.size() == 0) return NULL;
     return recursive_merge(givenLists, 0, givenLists.size()-1);
 }
Exemplo n.º 5
0
int main( int argc, char *argv[] )
{

    unsigned int i;
    hthread_time_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge =
        0, t_check = 0;

    setup_cache();
    printf( "-------------------------------------------------------\n"
            "ReconOS hardware multithreading case study (sort)\n"
            "(c) Computer Engineering Group, University of Paderborn\n\n"
            "eCos, single-threaded software version (" __FILE__ ")\n"
            "Compiled on " __DATE__ ", " __TIME__ ".\n"
            "-------------------------------------------------------\n\n" );

    data = buf_a;

    //----------------------------------
    //-- GENERATE DATA
    //----------------------------------
    printf( "Generating data..." );
    t_start = gettime(  );
    generate_data( data, SIZE );
    t_stop = gettime(  );
    t_gen = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- SORT DATA
    //----------------------------------
    printf( "Sorting data..." );
    for ( i = 0; i < SIZE; i += N ) {
        t_start = gettime(  );
        bubblesort( &data[i], N );
        t_stop = gettime(  );
        t_sort += calc_timediff_ms( t_start, t_stop );
    }
    printf( "done\n" );

    //----------------------------------
    //-- MERGE DATA
    //----------------------------------
    printf( "Merging data..." );
    t_start = gettime(  );
    data = recursive_merge( data, buf_b, SIZE, N, simple_merge );
    t_stop = gettime(  );
    t_merge = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- CHECK DATA
    //----------------------------------
    printf( "Checking sorted data..." );
    t_start = gettime(  );
    if ( check_data( data, SIZE ) != 0 )
        printf( "CHECK FAILED!\n" );
    else
        printf( "check successful.\n" );
    t_stop = gettime(  );
    t_check = calc_timediff_ms( t_start, t_stop );

    printf( "\nRunning times (size: %lu words):\n"
            "\tGenerate data: %llu ms\n"
            "\tSort data    : %llu ms\n"
            "\tMerge data   : %llu ms\n"
            "\tCheck data   : %llu ms\n"
            "\nTotal computation time (sort & merge): %llu ms\n",
            SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge );

    return 0;
}
Exemplo n.º 6
0
int main( int argc, char *argv[] )
{

    unsigned int i, start_count = 0, done_count = 0, j;
    timing_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge =
                                       0, t_check = 0, t_tmp;

    printf( "-------------------------------------------------------\n"
            "ReconOS hardware multithreading case study (sort)\n"
            "(c) Computer Engineering Group, University of Paderborn\n\n"
            "eCos, single-threaded hardware version (" __FILE__ ")\n"
            "Compiled on " __DATE__ ", " __TIME__ ".\n"
            "-------------------------------------------------------\n\n" );

#ifdef USE_CACHE
    printf( "enabling data cache for external ram\n" );
    XCache_EnableDCache( 0x80000000 );
#else
    printf( "data cache disabled\n" );
    XCache_DisableDCache(  );
#endif

    data = buf_a;

    //----------------------------------
    //-- GENERATE DATA
    //----------------------------------
    printf( "Generating data..." );
    t_start = gettime(  );
    generate_data( data, SIZE );
    t_stop = gettime(  );
    t_gen = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

#ifdef USE_CACHE
    // flush cache contents - the hardware can only read from main memory
    // TODO: storing could be more efficient
    printf( "Flushing cache..." );
    XCache_EnableDCache( 0x80000000 );
    printf( "done\n" );
#endif

    //----------------------------------
    //-- SORT DATA
    //----------------------------------
    // create mail boxes for 'start' and 'complete' messages
    cyg_mbox_create( &mb_start_handle, &mb_start );
    cyg_mbox_create( &mb_done_handle, &mb_done );
    // create sorting thread
    reconos_hwthread_create( 16,                                               // priority
                             0,                                                // entry data (not needed)
                             "MT_HW_SORT",                                     // thread name
                             hwthread_sorter_stack,                            // stack
                             STACK_SIZE,                                       // stack size
                             &hwthread_sorter_handle,                          // thread handle
                             &hwthread_sorter,                                 // thread object
                             (void*)UPBHWR_OSIF_0_BASEADDR,
                             XPAR_OPB_INTC_0_OSIF_0_INTERRUPT_INTR+1,
                             //                         ( void * ) XPAR_PLB_RECONOS_SLOT_0_BASEADDR,      // base address
                             //                         XPAR_OPB_INTC_0_PLB_RECONOS_SLOT_0_INTERRUPT_INTR + 1,     // interrupt
                             hwthread_sorter_resources,                        // resource array
                             2,                                                 // number of resources
                             0xFFFFFFFF, 0xFFFFFFFF
                           );
    cyg_thread_resume( hwthread_sorter_handle );

    printf( "Sorting data..." );
    i = 0;
    while ( done_count < SIZE / N ) {
        t_start = gettime(  );
        // if we have something to distribute,
        // put as many as possile into the start mailbox
        while ( start_count < SIZE / N ) {
            if ( cyg_mbox_tryput( mb_start_handle, ( void * ) &data[i] ) ==
                    true ) {
                start_count++;
                i += N;
            } else {                                                           // mailbox full
                break;
            }
        }
        t_stop = gettime(  );
        t_sort += calc_timediff_ms( t_start, t_stop );
        // see whether anybody's done
        t_start = gettime(  );
        if ( ( t_tmp = ( timing_t ) cyg_mbox_get( mb_done_handle ) ) != 0 ) {
            done_count++;
        } else {
            printf( "cyg_mbox_get returned NULL!\n" );
        }
        t_stop = gettime(  );
        t_sort += calc_timediff_ms( t_start, t_stop );
    }
    printf( "done\n" );


#ifdef USE_CACHE
    // flush cache contents
    // TODO: invalidating would suffice
    printf( "Flushing cache..." );
    XCache_EnableDCache( 0x80000000 );
    printf( "done\n" );
#endif


    //----------------------------------
    //-- MERGE DATA
    //----------------------------------
    printf( "Merging data..." );
    t_start = gettime(  );
    data = recursive_merge( data, buf_b, SIZE, N, simple_merge );
    t_stop = gettime(  );
    t_merge = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- CHECK DATA
    //----------------------------------
    printf( "Checking sorted data..." );
    t_start = gettime(  );
    if ( check_data( data, SIZE ) != 0 )
        printf( "CHECK FAILED!\n" );
    else
        printf( "check successful.\n" );
    t_stop = gettime(  );
    t_check = calc_timediff_ms( t_start, t_stop );

    printf( "\nRunning times (size: %d words):\n"
            "\tGenerate data: %d ms\n"
            "\tSort data    : %d ms\n"
            "\tMerge data   : %d ms\n"
            "\tCheck data   : %d ms\n"
            "\nTotal computation time (sort & merge): %d ms\n",
            SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge );


    return 0;

}
Exemplo n.º 7
0
void main()
{

    unsigned int i;
    timing_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge =
        0, t_check = 0;

    printf( "-------------------------------------------------------\n"
            "ReconOS hardware multithreading case study (sort)\n"
            "(c) Computer Engineering Group, University of Paderborn\n\n"
            "eCos/POSIX, single-threaded software version (" __FILE__ ")\n"
            "Compiled on " __DATE__ ", " __TIME__ ".\n"
            "-------------------------------------------------------\n\n" );

#ifdef USE_CACHE
    diag_printf( "enabling data cache for external ram\n" );
    //XCache_EnableDCache( 0x80000000 );
HAL_DCACHE_ENABLE();
#else
    diag_printf( "data cache disabled\n" );
    //XCache_DisableDCache(  );
HAL_DCACHE_DISABLE();
#endif

    data = buf_a;

    //----------------------------------
    //-- GENERATE DATA
    //----------------------------------
    printf( "Generating data..." );
    t_start = gettime(  );
    generate_data( data, SIZE );
    t_stop = gettime(  );
    t_gen = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- SORT DATA
    //----------------------------------
    printf( "Sorting data..." );
    for ( i = 0; i < SIZE; i += N ) {
        t_start = gettime(  );
        bubblesort( &data[i], N );
        t_stop = gettime(  );
        t_sort += calc_timediff_ms( t_start, t_stop );
    }
    printf( "done\n" );

    //----------------------------------
    //-- MERGE DATA
    //----------------------------------
    printf( "Merging data..." );
    t_start = gettime(  );
    data = recursive_merge( data, buf_b, SIZE, N, simple_merge );
    t_stop = gettime(  );
    t_merge = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- CHECK DATA
    //----------------------------------
    printf( "Checking sorted data..." );
    t_start = gettime(  );
    if ( check_data( data, SIZE ) != 0 )
        printf( "CHECK FAILED!\n" );
    else
        printf( "check successful.\n" );
    t_stop = gettime(  );
    t_check = calc_timediff_ms( t_start, t_stop );

    printf( "\nRunning times (size: %d words):\n"
            "\tGenerate data: %d ms\n"
            "\tSort data    : %d ms\n"
            "\tMerge data   : %d ms\n"
            "\tCheck data   : %d ms\n"
            "\nTotal computation time (sort & merge): %d ms\n",
            SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge );

}