Two important properties of an application are its communication workload and its computation workload [20]. The communication workload is a measure for the amount of communication in an application, given the input data. The computation workload is a measure for the amount of computation in the application, given the input data. In the YAPI run-time environment the communication workload is measured by counting the number of tokens that are traveling through the fifos. The communication workload can be printed by calling the following function after the application has ended:
void printCommunicationWorkload( const ProcessNetwork& n, std::ostream& o = std::cout); |
The output for an example application with five fifos is shown below. The first column lists the full names of the fifos. The column Wtokens lists the number of tokens that have been written to the fifo. The column Wcall lists the number of write calls, and the column T/W lists the average number of tokens per write call. Similarly the columns Rtokens, Rcalls, and T/R give the values for the read calls.
Communication Workload: ------------------------------------------------- | Wtokens Wcalls T/W Rtokens Rcalls T/R| |pfc.fifo1 1 1 1 1 1 1| |pfc.fifo2 10 10 1 5 5 1| |pfc.fifo3 10 10 1 10 10 1| |pfc.fifo4 1003 1003 1 1003 103 9| |pfc.fifo5 1003 1003 1 1003 1003 1| ------------------------------------------------- |
YAPI also supports the measuring and printing of computation workload. To measure the computation workload, the C/C++ code of the processes must be annotated with execute statements. An execute statement is a call of the protected member function execute of class Process. The argument of the execute statement is a symbolic instruction that represents the workload that is associated with a certain code fragment.
void Process::execute(const char* instr); |
In the YAPI run-time environment the number of execute calls are counted. These numbers can be printed with the function printComputationWorkload.
void printComputationWorkload( const ProcessNetwork& n, std::ostream& o = std::cout); |
The table below shows how the output may look like. The first column lists the full names of the processes, the second column lists the symbolic instruction names, and the third column lists the number of calls that occurred during execution. The processes ppc.prd1 and ppc.prd2 have executed the instruction produce 100000 times, ppc.cons has executed instruction start and stop once, and has executed instruction consume 200000 times.
Computation Workload: ----------------------------- |Process Instruction Count| |ppc.prd1 | | produce 100000| |ppc.prd2 | | produce 100000| |ppc.cons | | start 1 | | consume 200000| | stop 1 | ----------------------------- |
By associating execution times with the instructions, and by multiplying these execution times with the instruction counts, one can get a rough estimate of the total execution time of the application on a certain platform.