Profiling of Intel 86x64 (further referred to as Intel) platforms is a much more challenging task than profiling the simpler TTA architecture for several reasons. First, the measured clock-cycles (CPU cycles) may vary depending on the availability of the required data/instructions in the data/instruction caches. Second, neglecting the communication cost will not be irrelevant for a good accuracy of the results. Moreover, it is not possible to measure the communication cost in a partitioning-independent way, because the results obtained for one configuration will not be valid for the other [132]. Hence, the actors cannot be executed in isolation (as for the case of TTA), but rather in a given configuration (partitioning, scheduling, buffer dimensioning). Finally, execution of any process which is not written as a kernel module does not guarantee the exclusive ownership of the processor [134], which means that any interrupts may affect the accuracy of the results. In order to minimize this effect, the profiling is performed under the minimal Linux system with no unnecessary processes running and the hyper-threading and turbo-mode (DVFS) turned off from BIOS/UEFI.
The Intel-based PCs, which are the target platforms for several experiments discussed later in Chapter 10, are considered to consist of identical processors. In most cases, the profiling is performed for the mono-core configuration. The measurements of the clock-cycles consumed for the execution (or scheduling) of each action are performed via the benchmarking functions
RDTSC_tick()andRDTSC_tock()to start and stop the benchmarking, respectively. Most Intel processors have a per-core time-stamp counter register and using theRDTSC
andRDTSCPinstructions (which read this register), Intel CPUs allow developers to keep track of every CPU cycle. Although the main utility of theCPUIDinstruction is to load the processor information into the registers, it is used along withRDTSCinstruction to serialize the execution with no effect on program flow and guarantee that the benchmarking functions do not execute out of order. Separate intrinsic executions ofCPUIDandRDTSC, however, often result in large variances when used to benchmark the same piece of code. To solve this issue, Intel providesRDTSCPinstruction, which performs both operations (reading the time-stamp counter register and loading the processor’s info) in an intrinsic atomic instruction.
These two benchmarking functions are implemented using the in-line volatile assembly instructions which invoke the intrinsic instructionsRDTSC,RDTSCP, andCPUID. Despite the aforementioned obstacles, it has been demonstrated in prior works that the profiling performed via these instructions is quite stable [135]. In order to support a systematic and automated benchmarking of the whole dataflow program on Intel platforms, the profiling utility is integrated in the C AL to C code generation of ORCC [70].
5.3.1 Processing weights
The action weights are calculated based on the measurements of the clock-cycles elapsed betweenRDTSC_tick() andRDTSC_tock()and consider the computational part of each action, excluding the scheduler and the management of buffers. The location of the
RDTSC_tick()andRDTSC_tock()calls are depicted in Fig. 5.4.
The number of clock-cycles elapsed between theRDTSC_tick()andRDTSC_tock()are stored as a weight of a firing. The weights for each firing of a given action are stored as a list. The post-processing stage filters out the outliers, that is, the weights with extraordinary values that can result from the, mentioned earlier, interrupts occurring during the execution. After the filtering, the new values ofµ and σ2are calculated. The final processing weight for each action corresponds to the calculated mean value. The filtering is performed according to the threshold. Any values exceeding the threshold are removed from the list of firings. The threshold is calculated according to the mean value (µ) and variance (σ2), calculated for all profiled firings, using the following formula:
t hr eshol d = µ + 2pσ2 (5.1)
The weights remain dependent on the used configurations. All configurations (partitioning, scheduling, buffer dimensioning) impact the results, because they influence the availability
1 void actorA_action_x_body() {
2 int i;
3
4 RDTSC_tick();
5 // Computational part of action’s body
6 i = tokens_InputPort1[(index_InputPort1 7 + (0)) % SIZE_InputPort1]; 8 tokens_OutputPort1[(index_OutputPort1 9 + (0)) % SIZE_OutputPort1] = i; 10 RDTSC_tock(); 11
12 // Update ports indices
13 index_InputPort1 += 1;
14 index_OutputPort1 += 1;
15 rate_InputPort1 += 1;
16 }
Figure 5.4 – Intel processing weights clock-cycles measurement: pseudocode.
of data in the caches throughout the execution. Additionally, the partitioning configuration impacts also the communication cost related to token exchange between the actors. Hence, the results remain the most reliable only for the set of configurations that were originally used for profiling. In order to use the results of profiling obtained for one configuration to explore other configurations, preliminary experiments demonstrated that the most accurate results can be obtained if the profiling is performed for a mono-core execution and relatively big buffers.
Figures 5.5 and 5.6 illustrate well the differences between the profiling data obtained for T T A and Intel platforms (using a realistic example of, described later in Section10.1.2, MPEG4-SP decoder) and justify the necessity of applying the filtering for the case of an Intel platform. Then, Table 5.1 summarizes the statistical values collected during the profiling in both cases and after applying the filtering.
Platform Samples Average Min Max Variance
TTA 1600 549.73 547 567 24.37
Intel (Original) 1600 666.89 156 21224 5.13 × 106 Intel (Filtered) 1528 188.39 156 776 4.61 × 103
0 200 400 600 800 1000 1200 1400 1600 545 550 555 560 565 570 clock cycles average min max
Figure 5.5 – T T A profiling data of a single action: collected timing data of 1600 firings.
0 200 400 600 800 1000 1200 1400 1600 0 0.5 1 1.5 2 2.5 104 clock cycles average min max discarded values
(a) Unfiltered data. Red circles highlight the outliers (values higher than the t r eshol d )
0 200 400 600 800 1000 1200 1400 1600 100 200 300 400 500 600 700 800 clock cycles average min max (b) Filtered data
Figure 5.6 – Intel profiling data of a single action: collected timing data of 1600 firings.
5.3.2 Scheduling weights
The measurement of the clock-cycles related to the scheduling is performed using the same instructions, averaging and filtering mechanism. TheRDTSC_tick()andRDTSC_tock()
calls related to the profiling of scheduling cost are depicted in Fig. 5.7. For the case of schedul- ing weights, apart from the action executed, it is also important to record the action which
was executed before. Hence, the values of scheduling weights are always linked to a certain
transition (source - target action set) and stored in an appropriate map. The filtering is applied
within each transition. If a previously executed action was an action of the same actor, its name is stored in a map. An empty name means that the action was entered "from outside". This happens for the very first execution of a given actor or if the last executed action in a given partition belonged to another actor.
It must be emphasized that the scheduling weights obtained this way are related only to the internal scheduler inside each actor and do not include the cost of the scheduler inside a partition. The values of the weights obtained for each transition do not depend on the applied partitioning, scheduling nor buffer dimensioning configurations. The applied configurations (scheduling and buffer dimensioning), however, influence the occurrence of certain transitions. For instance, the set of possible transitions which are profiled can differ for small and big buffer sizes. In consequence, profiling one configuration and exploiting the results for exploration of other configurations means that certain transitions might not be profiled, hence they are not present in the resulting weights. Preliminary experiments demonstrated that the set of common transitions (overlapping between different configurations) is quite large, however the presence of some differentiating subsets cannot be eliminated.
5.3.3 Communication weights
The generation of communication weights is performed using the numap library [136]. This low-level memory profiling library is intended to be used for memory profiling in centralized shared memory systems. It was initially designed for profiling of the memory usage on Non Uniform Memory Access (NU M A) architectures and supports many micro-architectures from Intel. The implementation is portable, because according to the set of supported architectures, the correct hardware event to be used for memory read/write sampling is selected. The functions of the library count memory requests, generate memory samples and provide access to them for analyzing memory behavior of applications. The profiling can be performed for multiple NU M A nodes and multiple threads.
Since different samples are available (i .e., shared memory variables, global and local variables), the samples related to the buffers are extracted. Different runs of profiling are required for reading and writing data and for each operation different information is available. For each buffer present in the profiling report the following information about reading is provided:
• memory level that served the access (L1, L2, L3, LFB, Local RAM, Uncached Memory); • the number of accesses for each memory level;
• whether a memory hit or miss occurred.
In contrast, the information related to writing is limited to: • whether a memory hit or miss occurred in level L1; • the number of occurrences for each event.
The communication weight related to the reading operation for each buffer is calculated as a weighted arithmetical mean for the set of recorded events (memory level + hit/miss), where the values correspond to the average latency and the weight to a percentage of occurrences of certain events in the entire set of events, as illustrated in Equation 5.2. Table 5.2 presents a realistic example of the values obtained in the report. The calculation of the communication weight for this example is demonstrated in Equation 5.3. The communication weight related to the writing operation is calculated in the same way, based on just 2 samples (L1 hit, L1 miss) where some constants are specified as latencies. The value of these constants have been specified as maximum values (L1 hit, not-L1 hit, respectively) occurring for the reading events.
wj j0= Pn i =1linai Pn i =1nai (5.2)
Memory level Number of accesses (na) Average latency (l ) event
L1 1114 10.61 hit
L2 4 19.50 hit
L3 0 0.00 hit
LFB 6 137.08 hit
Local RAM 1 597.00 hit
Uncached memory 0.00 22 hit
Table 5.2 – Sample communication cost data.
wj j0=1114 ∗ 10.61 + 4 ∗ 19.50 + 6 ∗ 137.08 + 1 ∗ 597
1125 = 11.84 (5.3)
At this stage it must be emphasized that profiling with numap succeeds according to a certain sampling rate (Chapter 5 of [132]). Depending on that rate (and, obviously, on the length of the input stimulus used for profiling), some buffers can be represented with more samples than others, hence, the generated communication weight is more accurate. It is also possible that for some buffers the communication weight cannot be generated because of an insufficient representation of this buffer in the samples used to generate the report.
5.4 Profiling accuracy
An important problem related to profiling is the accuracy of the retrieved information which translates directly into the accuracy of the performance estimation methodology or the design space exploration heuristics. In general, modeling the architecture relying on the profiling and, in particular, on the limited set of measurements coming from the platform (i .e., the weight calculated according to the statistical properties) can be burdened with some errors. These general uncertainties of profiling result from multiple factors, such as: varying execution times resulting from interrupts, counting some instructions multiple times or intractable optimizations of the compiler [137].
Since different platforms provide different levels of accuracy, what is the acceptable level of discrepancy, for instance, in the performance estimation methodology based on profiling can be debated. For the purpose of design space exploration it can be assumed that the requirement is to ensure such a level of accuracy that permits correct evaluation of different design points and allows performing the moves in the considered design space efficiently and in a systematic way.
5.5 Conclusions
This Chapter presented a way to provide an abstract model of execution with the timing information, so that the execution essentials can be captured enabling a reliable comparison of different design points. The two discussed platforms are characterized with different properties, which contribute to the level of accuracy of the provided models. A TTA platform allows, in general, the creation of a very accurate model in a simple way, since the profiling results do not depend on the partitioning configuration and the communication cost can be neglected. For the case of Intel platforms, obtaining an accurate model is more difficult, since the partitioning-dependent communication cost must be introduced to ensure enough accuracy. Furthermore, the interrupts require applying additional filtering techniques.
1 void actorA_scheduler() { 2 3 lastSelectedAction = OUTSIDE; 4 RDTSC_tick(); 5 6 // jump to FSM state 7 switch(FSM_state) { 8 case my_state_state_1: 9 goto l_state_2; 10 case my_state_state_2: 11 goto l_state_3; 12 } 13 14 // FSM transitions 15 l_state_2: 16 if (isSchedulable_action_x) { 17 RDTSC_tock(); 18 currentSelectedAction = action_x; 19
20 // execute the action
21 action_x_body(); 22 23 lastSelectedAction = currentSelectedAction; 24 RDTSC_tick(); 25 } 26 else if (isSchedulable_action_y) { 27 RDTSC_tock(); 28 currentSelectedAction = action_y; 29
30 // execute the action
31 action_y_body(); 32 33 lastSelectedAction = currentSelectedAction; 34 RDTSC_tick(); 35 } 36 37 l_state_3: 38 if (isSchedulable_action_z) { 39 RDTSC_tock(); 40 currentSelectedAction = action_z; 41
42 // execute the action
43 action_z_body(); 44 45 lastSelectedAction = currentSelectedAction; 46 RDTSC_tick(); 47 } 48 }
Before attempting to solve the problem of design space exploration and optimization of dy- namic dataflow programs, it is important to clarify what are the exact requirements, properties, decision variables and constraints. To the best of the author’s knowledge, such a rigorous formulation of the design space exploration problem is still missing in the dataflow-related literature. Moreover, the available formulations mainly target only the SDF computation model which is characterized by several limitations, as discussed in Chapter 2. The current formulations respond also only partially to the demands of DDF , because when considering the partitioning and scheduling problems, they usually do not take into account the buffer dimensioning problem, nor its influence on the size of the partitioning and scheduling design space. Considering these subproblems, this Chapter presents a detailed formulation of the design space exploration (DSE ) problem which follows precisely the demands of dynamic
dataflow applications. The problem is formulated in terms of the decision variables, objective functions and constraints. It also considers how the general problem is specified (i .e., extended with additional constraints) when an execution on a given type of platform is considered. An example illustrating the problem instance sizes is also included.