Project

General

Profile

Statistics
| Branch: | Revision:

root / PORTING @ 97e29f40

History | View | Annotate | Download (3.9 KB)

1
 Porting an OMNeT++ model to Horizon
2
 =================================== 
3

    
4
 Porting a given model to run on top of Horizon is relatively straightforward.
5

    
6
  * New base class for modules
7
    In order to enable parallel execution in Horizon, modules need to inherit 
8
    from cAsyncModule instead of cSimpleModule. Simply replace the base class
9
    in all modules of the model. Additionally, remove the Module_Class_Members()
10
    macro if it is used in the module. This macro is not compatible with Horizon
11
    and also not needed. 
12
    
13
  * No findObject
14
    In Horizon, the ownership handling of OMNeT++ is partly disabled to allow for
15
    an efficient parallel execution: Child modules still know their parent, but the
16
    parents do not know their children. Hence, it is not possible to find a
17
    child object this way.
18
    cQueue provides a set of replacement methods that allow to search for an
19
    object in the queue:
20
     - findObjectByName(const char* name)
21
     - removeByName(const char* name)
22
     - containsByName(const char* name)
23
     
24
  * Random number generation
25
    Since the global random number generator of OMNeT++ is not thread-safe,
26
    every cAsyncModule contains a local random number generator. To use this,
27
    simply prefix every call to a random number generation method with the local
28
    object numGen:
29
     - uniform(a,b)  ==>  numGen->uniform(a,b)
30
    Seeding of these local random number generators is done by means of a global
31
    seed generator RNG. During the sequential initialization phase of the model,
32
    every model requests a seed for its local RNGs from the central seed generator. 
33

    
34

    
35
 Performance optimization
36
 ========================
37
 
38
 The migration process described above only allows to run a model on top of 
39
 Horizon, but it does not consider parallel performance. This section tries to
40
 give some hints on how to achieve a good parallel performance.
41
 
42
   * Specify event durations
43
     Horizon can only process events in parallel if 
44
       i) they are discrete and start at the same point in simulated time or
45
      ii) if they are expanded events, i.e., they span a period of simulated time,
46
          and those periods overlap.
47
     To define a durations for an expanded event, a specific method inside of the
48
     module needs to be implemented:
49
     
50
      - simtime_t getProcessingDelay(cMessage* msg)
51
     
52
     This method receives a message and returns the associated duration of this
53
     event. If it is not implemented, the default duration for an event is 0.
54
     
55
     NOTE: When defining an expanded event a few issues need to be considered:
56
     
57
      - Expanded events may only create new events which start AFTER the current
58
        event finished. I.e., if an event spans from 1.0s to 1.5s
59
        in the simulation, ALL events it sends and schedules may ONLY start at or
60
        after 1.5s in the simulation.
61
        One can access the duration of the current expanded event by calling
62
        getCurrentProcessingDelay() and add this to the send/scheduleAt call:
63
        send(msg, "gate")  ==>  sendDelayed(msg, getCurrentProcessingDelay(), "gate")
64
        
65
      - Defining expanded events changes the timing of the model. This might
66
        potentially mess up the order of events. 
67
     
68
   * Splitting functionality
69
     For data consistency reasons, only one event is active inside of each module.
70
     In order to achieve as much parallelism as possible, parallel computations
71
     that do not depend on each other should be conducted in separate instances
72
     of modules.
73
     Example: pathloss calculation. Multiple such calculations can run in parallel
74
     because the only depend on the position of the sender and receiver. If there
75
     is only one instance of the "PathlossModule", all calculations must be done
76
     sequentially. Hence, it is better to create multiple instances (for example
77
     one for each receiver module) which then calculate the pathloss in parallel
78
     to the other modules.
79
 
80