Changeset 65 for sources/src/gen_code.cc


Ignore:
Timestamp:
Oct 23, 2019, 12:53:07 PM (5 years ago)
Author:
bouyer
Message:

Various performance improvements for the parallel systemcass: cache-aligned
data structures, write only when needed, disable some unneeded barriers.

Fix bug in the non-openmp case: a pointer was not initialized

various style updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sources/src/gen_code.cc

    r63 r65  
    5050#include <fstream>
    5151#ifdef _OPENMP
    52     #include <omp.h>
    53 #endif
     52#include <omp.h>
     53#endif
     54#include <sys/types.h>
     55#include <unistd.h>
    5456
    5557#include "internal.h"
     
    240242}
    241243
    242 
    243 char * gen_scheduling_code_for_dynamic_link(method_process_list_t & transition_func_list,
    244         method_process_list_t & moore_func_list,
    245         strong_component_list_t * strongcomponents) {
    246     if (dump_stage) {
    247         cerr << "Generating C code for scheduling...\n";
    248     }
     244char *
     245gen_scheduling_code_for_dynamic_link (
     246               method_process_list_t           &transition_func_list,
     247               method_process_list_t           &moore_func_list,
     248               strong_component_list_t         *strongcomponents)
     249{
     250  if (dump_stage)
     251    cerr << "Generating C code for scheduling...\n";
    249252
    250253    // open temporary file
     
    258261    }
    259262
    260     o << "// generated by " << sc_version() << endl
    261         << "#include <casc.h>\n\n" << "#include <cstdio>\n\n"
    262         //  << "#include <iostream>\n\n"
    263         << "namespace sc_core {\n"
    264         << " typedef void (sc_module::*SC_ENTRY_FUNC)();\n"
    265         << " typedef void (*CASC_ENTRY_FUNC)(void *);\n";
     263  o << "// generated by " << sc_version () << endl
     264    << "#include <casc.h>\n\n"
     265    << "#include <cstdio>\n\n"
     266//  << "#include <iostream>\n\n"
     267    << "namespace sc_core {\n"
     268    << " typedef void (sc_module::*SC_ENTRY_FUNC)();\n"
     269    << " typedef void (*CASC_ENTRY_FUNC)(void *);\n";
    266270
    267271    const char * pmf_type = get_pmf_type();
     
    533537}
    534538
    535 
    536 void call_functions_in_parallel(function_call & fc) {
    537     int n = fc.func_number;
    538     int i;
    539     for (i = 0; i < n; ++i) {
    540 #if 0
    541         //defined(CONFIG_DEBUG)
    542         sc_module *m = (sc_module *) (fc.instance[i]);
    543         cerr << m->name() << endl;
    544         cerr << "thread #" << omp_get_thread_num() << endl;
     539void
     540call_functions_in_parallel (function_call &fc)
     541{
     542  int n = fc.func_number;
     543  int i;
     544  for (i = 0; i < n; ++i)
     545  {
     546#if 0 //defined(CONFIG_DEBUG)
     547    sc_module *m = (sc_module*)(fc.instance[i]);
     548    cerr << m->name () << endl;
     549    cerr << "thread #" << omp_get_thread_num () << endl;
    545550#endif
    546551        fc.function[i].pf(fc.instance[i]);
     
    566571 */
    567572
    568 unsigned int nb_func[2];
    569 static method_process_t **func_list[2];
     573unsigned int              nb_func[2];
     574static method_process_t        **func_list[2];
    570575static strong_component_list_t quasistatic_list;
    571576
     
    578583#endif
    579584
    580 static void Call(const method_process_t & m) {
    581     sc_module * mod = m.module;
    582     SC_ENTRY_FUNC func = m.func;
    583     //  CASC_ENTRY_FUNC   func = reinterpret_cast<CASC_ENTRY_FUNC> (m.func);
    584     // QM
    585     //cerr << "Exec " << mod->name() << "->" << m.name << endl;
    586     (mod->*func) ();
     585static
     586void
     587Call         (const method_process_t &m)
     588{
     589  sc_module        *mod  = m.module;
     590  SC_ENTRY_FUNC     func = m.func;
     591//  CASC_ENTRY_FUNC   func = reinterpret_cast<CASC_ENTRY_FUNC> (m.func);
     592  (mod->*func) ();
    587593}
    588594
     
    620626unsigned int num_omp_threads;
    621627
    622 void quasistatic_simulate_1_cycle(void) {
    623     int i;
    624 
    625     for (i = 0; i < nb_func[0]; ++i) {
    626         Call(*(func_list[0][i]));
    627     }
     628void quasistatic_simulate_1_cycle (void)
     629{
     630        int i;
     631
     632        for (i = 0; i < nb_func[0]; ++i)
     633                Call (*(func_list[0][i]));
     634#ifdef _OPENMP
    628635#define USE_BUSY_WAIT 1
    629     update();
     636#if 0
    630637#if USE_BUSY_WAIT
    631     expected_globaltime += num_omp_threads;
    632     if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime) {
    633         last_wait_up++;
    634     }
    635     __asm volatile("mfence");
    636     while (globaltime < expected_globaltime) {
    637         busy_wait_up++;
    638         __asm volatile("lfence");
    639     }
     638        expected_globaltime += num_omp_threads;
     639        if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
     640                last_wait_f0++;
     641        __asm volatile("mfence");
     642        while (globaltime < expected_globaltime) {
     643                busy_wait_f0++;
     644                __asm volatile("lfence");
     645        }
    640646#else
    641647    #ifdef _OPENMP
     
    643649    #endif
    644650#endif
    645 
    646     for (i = 0; i < nb_func[1]; ++i) {
    647         Call(*(func_list[1][i]));
    648     }
    649 
     651#endif
     652#endif // _OPENMP
     653
     654        update();
     655
     656#ifdef _OPENMP
    650657#if USE_BUSY_WAIT
    651     expected_globaltime += num_omp_threads;
    652     if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime) {
    653         last_wait_f1++;
    654     }
    655     __asm volatile("mfence");
    656     while (globaltime < expected_globaltime) {
    657         busy_wait_f1++;
    658         __asm volatile("lfence");
    659     }
     658        expected_globaltime += num_omp_threads;
     659        if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
     660                last_wait_up++;
     661        __asm volatile("mfence");
     662        while (globaltime < expected_globaltime) {
     663                busy_wait_up++;
     664                __asm volatile("lfence");
     665        }
     666
    660667#else
    661668    #ifdef _OPENMP
     
    663670    #endif
    664671#endif
    665     if (!quasistatic_list.empty()) {
     672#endif // _OPENMP
     673
     674        for (i = 0; i < nb_func[1]; ++i)
     675                Call (*(func_list[1][i]));
     676
    666677#ifdef _OPENMP
     678#if USE_BUSY_WAIT
     679        expected_globaltime += num_omp_threads;
     680        if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
     681                last_wait_f1++;
     682        __asm volatile("mfence");
     683        while (globaltime < expected_globaltime) {
     684                busy_wait_f1++;
     685                __asm volatile("lfence");
     686        }
     687#else
     688#pragma omp barrier
     689#endif
     690#endif // _OPENMP
     691
     692        if (!quasistatic_list.empty()) {
    667693#pragma omp master
    668 #endif
    669         {
    670             quasistatic_mealy_generation();
    671         }
     694                {
     695                quasistatic_mealy_generation ();
     696                }
     697#ifdef _OPENMP
    672698#if USE_BUSY_WAIT
    673         expected_globaltime += num_omp_threads;
    674         if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime) {
    675             last_wait_ml++;
    676         }
    677         __asm volatile("mfence");
    678         while (globaltime < expected_globaltime) {
    679             busy_wait_ml++;
    680             __asm volatile("lfence");
    681         }
     699                expected_globaltime += num_omp_threads;
     700                if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
     701                        last_wait_ml++;
     702                __asm volatile("mfence");
     703                while (globaltime < expected_globaltime) {
     704                        busy_wait_ml++;
     705                        __asm volatile("lfence");
     706                }
    682707#else
    683708    #ifdef _OPENMP
     
    685710    #endif
    686711#endif
    687     }
    688 }
    689 
    690 
    691 void gen_scheduling_code_for_quasistatic_func(method_process_list_t & transition_func_list,
    692         method_process_list_t & moore_func_list,
    693         strong_component_list_t * mealy_func_list) {
    694     if (dump_stage) {
    695         cerr << "Generating quasi static scheduling...\n";
    696     }
    697 
    698     nb_func[0] = transition_func_list.size();
    699     nb_func[1] = moore_func_list.size();
    700 
    701     func_list[0] = (method_process_t**) malloc(sizeof (method_process_t*) * nb_func[0]);
    702     func_list[1] = (method_process_t**) malloc(sizeof (method_process_t*) * nb_func[1]);
    703 
    704     unsigned int i;
    705     for (i = 0; i < nb_func[0]; ++i) {
    706         func_list[0][i] = (transition_func_list[i]);
    707     }
    708 
    709     for (i = 0; i < nb_func[1]; ++i) {
    710         func_list[1][i] = (moore_func_list[i]);
    711     }
    712 
    713     if (mealy_func_list != NULL) {
    714         quasistatic_list = *mealy_func_list;
    715     }
    716 
    717     if (dump_stage) {
    718         cerr << "Generating quasi static scheduling done.\n";
    719     }
     712#endif // _OPENMP
     713        }
     714
     715}
     716
     717void
     718gen_scheduling_code_for_quasistatic_func (
     719            method_process_list_t   &transition_func_list,
     720            method_process_list_t   &moore_func_list,
     721            strong_component_list_t *mealy_func_list)
     722{
     723  if (dump_stage)
     724    cerr << "Generating quasi static scheduling...\n";
     725
     726  nb_func[0] = transition_func_list.size();
     727  nb_func[1] = moore_func_list     .size();
     728
     729  func_list[0] = (method_process_t**) malloc (sizeof (method_process_t*) * nb_func[0]);
     730  func_list[1] = (method_process_t**) malloc (sizeof (method_process_t*) * nb_func[1]);
     731
     732  unsigned int i;
     733  for (i = 0; i < nb_func[0]; ++i)
     734    func_list[0][i] = (transition_func_list[i]);
     735
     736  for (i = 0; i < nb_func[1]; ++i)
     737    func_list[1][i] = (moore_func_list[i]);
     738
     739  if (mealy_func_list != NULL)
     740    quasistatic_list = *mealy_func_list;
     741
     742  if (dump_stage)
     743    cerr << "Generating quasi static scheduling done.\n";
    720744}
    721745} // end of sc_core namespace
Note: See TracChangeset for help on using the changeset viewer.