## 2 Background and Related Works
### Approximate Computing (AC)  
Several applications can accept results with some degree of inaccuracy. This feature can be used, through the approximate computing paradigm, to improve the efficiency of a system [11]. The improvements can be made in the performance of the system, when executing a task in a shorter time; in energy, by reducing the power consumption that is normally required for a given task; and in area, when the size of the chips is reduced due to the use of approximated logic circuits or to an increase in the density of semiconductor memories [17]. Approximate computing (AC) can be achieved by means of different techniques at the hardware and software levels [18]. At the hardware level [19; 20; 21], inaccurate but more efficient components can be used. Additionally, software-based AC techniques [22; 23] prevent physical modification of the system to obtain approximated results. At the software level, the aim is to increase efficiency by reducing calculations or access to memory. The most important AC techniques at the software level include:  
* Bit width reduction: This technique is based on precision reduction (number of bits that would normally be used) in floating-point numbers. In this way, energy efficiency and performance can be improved by sacrificing accuracy in the results [24]. On the other hand, when using the highest precision available in a microprocessor, code execution could take more time, so energy consumption would increase. On the other hand, if the representation of the data to put into operation is done using a smaller number of bits, it could have a lower energy consumption by reducing the accuracy in the result. * Float point to fixed point conversion: Following the same principle of the prior technique, a floating-point variable can be replaced by a fixed-point variable [25]. The computation of real data type operations using a fixed-point number representation could be executed faster than operations using a floating point representation. For instance, this technique could be used for the computation of arithmetical operations in systems that lack a floating point unit (FPU), such as small microcontrollers. * Code perforation: This technique identifies sections of code that can be discarded, without greatly affecting the results, to reduce computational costs. An example is to reduce the number of iterations in a loop, i.e., loop perforation [26; 27]. This is a technique that transforms a loop to execute a subset of iterations of the original loop. By executing fewer iterations, the perforated loop will have a shorter execution time. Nevertheless, reducing iterations in a loop changes the result obtained with the original loop. Sometimes that difference may not be significant, but in other cases, the percentage of error between the results can be considerable, so the designer must establish a trade-off between accuracy of results and execution time. * Synchronization elision: In multi-core systems, one of the most time-consuming tasks is synchronization. This technique implies a relaxing synchronization in parallel applications to reduce the associated costs [28]. Traditional relaxing synchronization techniques are based on the identification of scenarios where synchronization is not necessary. In contrast, this new technique takes advantage of the possibility of reducing the accuracy in the result without having a great impact on the behavior of the application. In this way, the synchronization is relaxed to improve performance at the expense of inexact results. It should be noted that the applicability of the AC techniques mentioned above depends strongly on the type of application, that is, on the nature of the algorithm to be approximated. Firstly, each technique fits to particular conditions of the applications; for example, in programs lacking iterative loops, it would not be valid to implement loop perforation. The float-point to fixed-point conversion could be a suitable alternative instead.