S A S Cortus

Michael Chapman
email: michael.chapman@cortus.com

Erven Rohou
email: erven.rohou@inria.fr

Rue De Freyr

D2.1 -Report on selected relevant metrics: design and implementation choice Project Partner Contact Information

Table of Contents

The present deliverable surveys a number of metrics found in literature, which are considered as relevant for assessing performance and energy consumption during our studies conducted within the CONTINUUM project. These metrics are summarized in the following

Introduction

Today, high-performance computation has become appealing for scientific/intensive applications that are running on high performance microprocessors. The number of cores and processors frequency have been increasing through the last years. Frequency and energy consumption are two proportional terms related by the supplied voltage of a processor, i.e., the energy consumption in CMOS circuit has a direct relationship with working frequency f and the square of the supplied voltage V , as defined in the following relation: P = CV 2 f , where P is the power and C is capacitance. P is expressed in Watts. Hence, increasing the frequency leads to increase the power consumption of the processor. Let us recall that power is the rate at which energy is consumed or produced. In the context of calculus, power is the derivative of energy, while the latter is the integral of power (see Figure 1). Energy consumption and power dissipation became an important design constraint in today's highperformance microprocessors. The gap existing between processor performance and memory performance makes memory-access an influencing performance factor in high-end computing. Several researchers [START_REF] Bellas | Architectural and compiler support for energy reduction in the memory hierarchy of high performance microprocessors[END_REF][START_REF] Panda | Memory Issues in Embedded Systems-on-Chip: Optimizations and Exploration[END_REF] have identified the memory components as the energy bottleneck of an entire system. For that reason, different memory hierarchies have been proposed to reduce the energy consumption of memory's subsystems and the most famous ones are SRAM caches and scratchpad memories.

Nevertheless, SRAM caches suffer from high leakage power, which dominates the total energy consumption in the on-chip memory system. To mitigate this problem, new non-volatile memory technologies such as phase-change RAM (PRAM) and spin-torque transfer magnetoresistive RAM (STT-RAM) have seen the light of day. They are prominent technologies that are used as alternative on-chip memories with the advantages of low leakage and high density. Yet, non-volatile memories are also suffering from their limited endurance, higher write latency and energy.

On the other hand, compilers, traditionally, are not directly exposed to energy aspects. However, with all the weight given to energy consumption, it is worthy to investigate how the compiler optimizations could have tremendous impacts on the overall energy consumption. As the main factor for activity on processor and memory systems, software has a signification effect on the energy consumption of the entire system. Still, developing new power-aware compiler optimizations and combining them with performance-oriented compiler optimizations is the focus of several researches. Furthermore, in order to optimize compilers for a specific objective, performance models and metrics are the primary keys that help to make efficient transformations to the program code. Indeed, these keys indicate to the compiler which transformations should be selected to achieve the goal whether in terms of performance or energy or even both. The common metrics used in literature are time and energy per access in memory hierarchy. Although these two metrics often behave similarly, moving down in memory levels makes both time and energy increase, which let us conclude that a memory architecture that has a good performance has also a good energy consumption. In spite of that, this conclusion may lead us to incorrect interpretation for the following reasons:

• time and energy do not increase in the same way,

• the performance is a worst-case quantity but the power is an average-case quantity [START_REF] Benini | System-level power optimization: Techniques and tools[END_REF] which means that improving performance for some critical computations may surprisingly be the cause of an increase in energy consumption. The notion of critical path has been used in many performance models. A critical path is a sequence of instructions or activities that will influence over the whole program execution time. In the context a performance, if an optimization is performed based on the non-critical path, performance is not affected and the optimization could be beneficial. However, in the context of power/energy, this is unreliable. Any activity, whether on or off the critical path will play a part in the overall power dissipation and energy usage [START_REF] Kremer | Low power/energy compiler optimizations[END_REF].

As software execution corresponds to performing operations on hardware, as well as accessing and storing data. It requires power dissipation for computation, storage and communication. Beside the fact that the energy consumed during execution is very important, reducing the code size and thus, the storage cost of a program, is the classical goal of compilers. The energy cost of executing a program relies on the machine code and the target machine. Therefore, for a target architecture, energy cost is bound to machine code and consequently to compilation. Hence, it is the compilation process itself that strikes energy consumption. Traditional optimizations such as common sub-expression elimination, partial redundancy elimination, silent stores elimination or dead code elimination increase the performance of a program by reducing the work to be done during program execution [START_REF] Muchnick | Advanced Compiler Design and Implementation[END_REF][START_REF] Aho | Compilers: Principles, Techniques, and Tools[END_REF]. Clearly, reducing the workload may also result in power/energy savings. Memory hierarchy optimizations play with latency and data placement. Optimizations such as loop tiling and register allocation try to keep data closer to the processor in order be accessed more faster. Memory optimizations may also contribute to reduce energy consumption. Loop tiling tries to keep a value in an on-chip cache instead of an off-chip memory and register allocation optimization try to allocate data in a register instead of the cache. Both techniques allow to save power/energy due to reduced switching activities and switching capacitance [START_REF] Kremer | Low power/energy compiler optimizations[END_REF].

A good compiler is a compiler based on efficient metrics. So definitely, bad metrics will directly affect performance as well as energy. At this stage of work, we focus on metrics that we intend to use in our future work. There is a fundamental difference in the models and metrics used for performance (CPU and memory) and those for power/energy optimizations. While memory is the bottleneck for performance, how to measure and evaluate memory systems has become an important issue facing the high performance computing community. In the following sections, we will detail the metrics that are the most commonly used in literature.

Miss rate/ hits rate / misses per instruction

Miss-rate (MR), hit-rate (HR) and misses per instruction are often used to measure the performance of a certain cache configuration. The miss-rate is the number of misses per total cache access and the hit-rate is the number of cache hits per total accesses. They are computed as follows: HR = no. of hits total no. of accesses M R = no. of misses total no. of accesses Given the above definitions, the number of misses per instruction (MPI) is therefore equal to:

M P I = M emory accesses per instruction * M R
Besides the miss rate, hits rate and the number, the cache size is an important factor as well. It involves area and miss rate. Large cache size means higher hit rate and lower miss rates in instructions cache as well as data cache. If the cache line size is increased, then the miss rate is reduced. If the number of cache lines is increased, then the miss rate can be reduced if the block size or the degree of set associativity is also increased. Here, we differentiate direct-mapped caches and set-associative caches. A direct-mapped cache with a large block size performs better than a set associative cache of the same size. Increasing block size improves the instruction cache hit rates.The effect on the hit rate of a data cache while increasing the block size is not as apparent as in the instruction cache. In the other hand, a set associative cache with a large degree of set associativity does better than a direct-mapped cache of the same size. Increasing the degree of set associativity improves the data cache hit rates. The effect on the hit rates of an instruction cache while increasing the degree of associativity is in contrary not as apparent as in the data cache [START_REF] Su | Cache design trade-offs for power and performance optimization[END_REF].

We should note that even if large cache size means higher hit rate, larger size caches are more expensive and slightly slower than smaller caches due to the larger number of control gates.

Number of cycles per instruction

A single machine instruction may take one or more CPU cycles to terminate. The average CPI of a program is the average CPI of all instructions executed on a given CPU design. It is expressed by:

CP I = CP U clock cycles inctructions count
Several code optimizations focus on reducing the number of cycles needed to run an application, but they might not decrease consumed energy as well, as they can create very complex transformations that may increase the energy used by the processor for computation. Another form of this metric is its inverse: Number of Instructions Per Cycle IPC. It has been widely used as a major performance evaluation metric in the computer architecture community. It reflects the overall performance in terms of the number of executed instructions per cycle:

IP C = 1 CP I
When a profiler tells you that the average CPI is equal to 2,that means that IPC is equal to 1 2 = 0.5. This level of performance would be rather bad for modern superscalar CPUs that can reach 4 Instructions Per Cycle (Intel). Therefore, the ideal CPI for modern processors is 1 4 = 0.25 Moreover, the impact of a miss on CPI is the cost of a cache miss in terms of time. In the literature, it is known as the miss penalty. For example, the miss penalty on the cache L1 correspond to the required time to access data in the lower level of cache L2. It is equal to:

M iss P enaltyL1 = Hit LatencyL2 * Hit RateL2 + M iss RateL2 * M iss P enaltyL2

Branch misprediction rate

Branch prediction is a fundamental component of modern pipelined architectures. It resolves a branch hazard by predicting which path will be taken to avoid stalling. The cost of stalling is directly related to CPI. Branch misprediction rate is a system performance metric because it relies on predictor accuracy. If a misprediction occurs, the entire pipeline needs to be flushed. There are dynamic and static methods for branch prediction. Dynamic branch prediction depends on program behaviour. It uses information Version 2.0 (2016) Confidentiality: Public Distribution about taken or not taken branches collected at run-time to predict the outcome of a branch. It is implemented in hardware. The most common algorithm is based on branch history. On the other hand, static prediction is the simplest branch prediction technique because it does not require information about the dynamic history of a program execution. It predicts the outcome of a branch based uniquely on the branch instruction. The simplest predictors predict which branch is always taken or to which one is always not taken. Another way is to use a profiler and some training input data to predict the branch direction that was most frequently taken.

Average Memory Access Time

The Average Memory Access Time (AMAT) is a metric that allow to analyze memory system performance. AMAT is the conventional metric to measure and analyze the influence of locality on data access latency [START_REF] Dubois | Parallel Computer Organization and Design[END_REF]. It can be used recursively to measure the impact of locality throughout all layers of the memory hierarchy and is widely used in memory system design and optimization.

AMAT depends on three terms: hit latency, miss rate, and miss penalty. It is calculated by taking the product of miss rate and miss penalty and adding it to the hit latency:

AM AT = Hit LatencyL1 * Hit RateL1 + M iss RateL1 * M iss P enaltyL1.
Then, the M iss P enaltyL1 can be replaced by its formula:

AM AT = Hit LatencyL1 * Hit RateL1+
M iss RateL1 * (Hit LatencyL2 * Hit RateL2 + M iss RateL2 * M iss P enaltyL2)

On the other hand, AMAT is in accordance with data access whether it is a hit or a miss, which means that the memory only supports sequential accesses and do not support multiple simultaneous accesses. For this reason, AMAT has been extended to take into consideration the modern memory systems. The new metric is called Concurrent-AMAT (C-AMAT). It combines the influence of data locality and concurrency. C-AMAT can be applied recursively to each layer of the memory hierarchy and reduces to AMAT when there is no data concurrency. C-AMAT uses two new parameters, hit concurrency and miss concurrency. It also introduces the notion of a pure miss, which is a miss that contains at least one pure miss cycle. A pure miss cycle is a miss cycle that does not overlap with a hit cycle. Using pure misses, C-AMAT adapts the definition of miss rate and average miss penalty of AMAT to pure miss rate and pure average miss penalty, as follows:

M iss rate = total no. of pure misses total no. of accesses

The average miss penalty, considering only pure miss accesses is: C-AMAT is based on the following assumptions [START_REF] Sun | Concurrent average memory access time (c-amat)[END_REF]:

AM P = sum of
1. reducing the number of pure misses is more relevant to the context of performance's improvement, 2. as data locality doesn't always improve performance, optimizations ought to balance between data locality improvement and concurrency.

Access Per Cycle

Based on the concept of IPC, which is a widely used system-performance metric, designed to measure CPU performance but does not reflect memory performance, Access Per Cycle is proposed to evaluate memory performance. It can be applied at each level of memory hierarchy, i.e, L1, L2,... It is calculated as the quotient of the overall memory accesses requested at a certain memory level (load/store) by the total cycles required by these accesses at that level. Let M denote the total data access (load/store) at a certain memory level, and T denote the total cycles consumed by these accesses. According to the definition, AP C is expressed by: AP C = M T A special characteristic of APC is that it separates memory evaluation from CPU evaluation and therefore allows to evaluate better data-intensive applications. System performance should correlate with memory performance, and if a memory performance metric does not correlate with system performance then this metric is probably missing important characteristics of memory system. Thus, correlation between IPC and APC is used to verify the correctness of APC. Wang et al. [START_REF] Wang | Apc: A novel memory metric and measurement methodology for modern memory systems[END_REF][START_REF] Sun | Apc: A performance metric of memory systems[END_REF] showed that among other memory metrics (Hit Rate, Hits Per 1K Instruction, Average Miss Penalty and Average Memory Access Time), APC has the highest correlation with IPC.

Energy metrics 4.1 Power

A processor works at a given power expressed as Watt (W). There are several factors contributing to the CPU power consumption. The two major types of power dissipations occurring in a CMOS circuit are: dynamic power consumption and static dissipation. The former one is due to the charging and discharging of capacitance or due to the switching activities of the circuit and the latter is due to transistor leakage currents. The power consumption of a circuit CMOS is represented by: P = CV 2 f where C is the effective load capacitance, v the supply voltage and f the clock frequency. According to Version 2.0 (2016) Confidentiality: Public Distribution this relation, we can see that the power consumption of the processor depends linearly on the effective capacitance, supply voltage and clock frequency. Thus, by changing the voltage and frequency, the power dissipation of the processor can be managed. For this reason, different techniques that aim to minimize the power consumption such as Dynamic Voltage/Frequency Scaling and Dynamic Power Management, try to adjust the voltage/frequency in order to conserve power or to reduce it.

Energy

As explicit as it is, the energy metric represents the energy consumption of a system. Different formulas have been proposed to estimate the energy consumed by a system using other performance metrics. Most of today's processors include dedicated hardware performance counters for debugging and measurement. These counters allow to create power models and measure the energy more precisely.

Isci et al. in [START_REF] Isci | Runtime power monitoring in high-end processors: Methodology and empirical data[END_REF] proposed a runtime power modelling methodology based on using hardware performance counters to estimate component power breakdowns for the Intel Pentium 4 processor.

In asymmetric multi-core architectures in which we are interested, it integrates cores with different power and performance characteristics, which makes mapping workloads to appropriate cores a challenging task. [START_REF] Pricopi | Powerperformance modeling on asymmetric multi-cores[END_REF] develop power-performance model for commercial asymmetric multi-core: ARM big.LITTLE (see Figure 2). Power and performance are modelled differently. While performance modelling is a combination of mechanistic and empirical modelling, power modelling is based on regression analysis. The aim is to predict, at runtime, the power, performance behaviour of an application on a target core (big or little), given its execution profile on the current core, where the cores share the same ISA but has heterogenous micro-architecture. A simple linear regression model is used to estimate the power consumption in terms of available performance counters. However, the performance counters available on one core are not the same available on the other core. For example, the big core provides the L2 cache write access counter but the small core does not provide it. Moreover, on asymmetric cores, the memory hierarchy and the branch predictors may not be identical across different core types, as it is the case in ARM big.LITTLE.

In big.LITTLE platform, the small cores are superscalar in-order, power efficient Cortex-A7 processors. Thus, there is no need to model power for the small cores. In contrary, the big cores (out-of-order A15) are very energy-demanding. That's why it is essential to model application-specific power Page 8

Version 2.0 (2016) Confidentiality: Public Distribution consumption on A15. The power consumption of A15 depends on the pipeline behaviour and the memory behaviour of the application. The power consumption in the memory hierarchy is determined by the number of L1 Inst, L1 Data, L2, and memory access. The small cores are connected to a simpler cache system in order to increase the power efficiency, while the big cores are connected to a more complex memory that supports higher memory throughput, which increases the overall performance. The main challenge to tackle in estimating the power consumption of an application on the big core while running it on the small core is that we have to predict the access profile. In order to predict the CPI value of core P2 while running on core P1, the values of the following performance counters need to be predicted: number of first level data and instruction cache miss (missL1D, missL1Inst), number of last level cache miss (missL2) and the number of branch mispredictions (missbr). Pricopi et al. proposed a combination of compile-time analysis, mechanistic modelling, and linear/non-linear regressions to create an accurate model that estimates the cache miss and branch misprediction rates on the target core, solely from the information available on the current core.

Therefore, energy can be computed relying on power models and estimation of factors such as missL1D, missL1Ins, missL2 and missbr or relying on hardware counters. The unity of measurement is Joules(J). In this work, as a concrete measurement of energy consumption, we will use the simulator developed by LIRMM that gives the overall consumed energy [START_REF] Delobelle | Flot automatique d'évaluation pour l'exploration d'architectures à base de mémoires non volatiles[END_REF]. It consists of a combination of three simulators: gem5, NVSim and McPAT, that are all performance-based frameworks.

Energy Delay Product

The energy delay product concept is based on the trade off existing between performance and energy consumption. It is a metric that considers both time and energy. It is defined as: EDP = E * t [START_REF] Marković | DSP Architecture Design Essentials[END_REF]. The graph illustrated in Figure 3 represents the energy curve and the delay curve. We observe that as V DD is scaled down, the delay decrease and the energy consumed increased. However, the EDP curve reaches a minimum before the energy curve. Therefore, EDP is minimized between the minimum energy and the minimum delay. Hence, choosing the optimal V DD edp for EDP depends on the weight given to energy and delay. If the weight of energy is bigger than the weight of performance, V DD Energy will tend to be decreased aggressively, which means that one can trade increased delay for lower energy. In the contrary, if performance has the bigger weight, then the emphasis will be on the delay and V DD Delay will be greater than V DD Energy . The overall can be summarized as:

V DD Energy < V DD edp < V DD Delay .

Resynchronization time

The modern processors support different operating modes (power modes/energy modes), each consuming a different amount of energy. Memories and other peripherals are also equipped with this feature (e.g., the RDRAM technology provides up to six power modes) [START_REF] Delaluz | Hardware and software techniques for controlling dram power modes[END_REF]. The power reduction is determined by which regions of the chip are turned off and how they are turned off. This is directly related to the latency (resynchronization time), which is determined by how long these regions need to transition back to the active state once the idle period is over. For this reason, the low power modes must be enabled and disabled at the right time, to avoid the cost of resynchronization, which is defined as the number of cycles required to get back to active state

Activity level for a program region

Another possible metric for energy is the activity size at a given point during program execution and total amount of activities for a program region [START_REF] Kremer | Low power/energy compiler optimizations[END_REF]. For an optimizing compiler, the activity size could be the number of executed instructions at a given point. Assuming that each instruction is associated with a certain amount of power, scheduling instructions and reordering them may have an impact on the power consumption at a certain time. This could be useful in case of partitioning code for an heterogeneous architecture and region-based compilation where the compiler is allowed to partition the program into new set of compilation units called regions.

Non volatile memories

Emerging non-volatile RAMs (NVRAMs), and generally non-volatile memories (NVM), have zero standby power, high density and non-volatility, which are useful features [START_REF] Mittal | A survey of architectural approaches for managing embedded dram and non-volatile on-chip caches[END_REF][START_REF] Zhao | Memory and storage system design with nonvolatile memory technologies[END_REF]. However, they also have the following limitations:

• relatively long and asymmetric access latencies, compared to conventional DRAM,

• high dynamic power consumption for write operations,

• limited write endurance.

Based on these characteristics, there are three categories of NVRAMs:

• NVRAMs with long access latencies for both read and write operations (e.g., PCRAM and Flash memory),

• NVRAMs with long write latencies and read access latencies comparable to DRAM (e.g., STT-RAM),

• NVRAMs with performance very close to and even slightly better than DRAM (e.g., RRAM). In the CONTINUUM project, we focus more on the second category because it represents prominent opportunities. STT-RAM have been recently considered for cache-level integration. The RRAM technology is not mature enough for consideration in our forthcoming studies, which will largely focus on the cache memory hierarchy. There are already some existing design exploration frameworks [START_REF] Senni | Potential applications based on NVM emerging technologies[END_REF][START_REF] Senni | Exploring MRAM technologies for energy efficient systems-on-chip[END_REF][START_REF] Senni | Emerging non-volatile memory technologies exploration flow for processor architecture[END_REF] that could support these studies. We will partly rely on them by adopting tools like gem5 [START_REF] Binkert | The gem5 simulator[END_REF] and NVSim [START_REF] Dong | A circuit-level performance, energy, and area model for emerging nonvolatile memory[END_REF] for simulation and evaluation.

Different approaches have been proposed to mitigate the limitations of NVMs. The most common idea is to manage thoroughly the writes operations with the objective of reducing the number of writes activities on NVRAMs. Whence, hybrid memory systems were rigorously been studied and several approaches were proposed, based on data placement and data migration from NVRAM to the other type of memory. To stay in the context of metrics, hybrid memories will be discussed in futur works with more details. According to the characteristics of NVRAMs, the number of writes and Read/write ratio are used in order to benefit from them and quantify their opportunities.

The read/write ratio is inversely proportional to the number of writes. Thus, a higher read/write ratio signifies less intensive write program/benchmark. Several existing studies have proposed approaches to mitigate the cost of write operations. Basically, the common idea is to minimise the number of write operations on NVRAM. Zhou et al. [START_REF] Zhou | Energy reduction for stt-ram using early write termination[END_REF] proposed early write termination (EWT) to reduce high write energy for MRAM. The EWT technique was proposed to detect and terminate redundant write operations to remove unnecessary write operations.

Hu et al. [START_REF] Hu | Reducing write activities on non-volatile memories in embedded cmps via data migration and recomputation[END_REF] proposed two optimization techniques: write-aware scheduling and recomputation. These two techniques aim to minimize write activities on NVRAM while speeding up the completion time of programs and extending NVRAM's lifetime. Smullen et al. [START_REF] Smullen | Relaxing nonvolatility for fast and energy-efficient stt-ram caches[END_REF] presented an approach for redesigning NVRAM (e.g., STT-RAM) cells to reduce the high dynamic energy and slow write latencies. They used the retention time which is the time that indicates how long the data can be kept in a NVRAM cell after it had been stored. Reducing the retention time leads to lower write current, hence, to less consuming write operations. Other important approaches are also presented in the context of hybrid memories, typically, using SRAM and NVRAMS and migrating as much as possible write operations to SRAM. This deliverable presented some relevant metrics accordingly to literature. Measuring power and energy is not an obvious task. Different factors contribute in the energy consumption of an entire computing system. Choosing the right factors is the first step towards an efficient energy measurement. The next step consist in specifying and designing energy-aware optimizations using NVMs as shown in our very recent work [START_REF] Péneau | Loop optimization in presence of STT-MRAM caches: A study of performanceenergy tradeoffs[END_REF]. We want to investigate new compilation techniques that allow us to exploit the advantages of emerging non-volatile memory technologies.

  time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Miss rate/ hits rate / misses per instruction . . . . . . . . . . . . . . . . . . . . . . . 3.3 Number of cycles per instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Branch misprediction rate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 Average Memory Access Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6 Access Per Cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Energy metrics 4.1 Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Energy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Energy Delay Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 Resynchronization time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5 Activity level for a program region . . . . . . . . . . . . . . . . . . . . . . . . . . .

Figure 1 :

 1 Figure 1: Energy as the integration of power over time: Energy = b a P (t)dt

  time CPU execution time is the time required to complete the execution of a program. It is measured in clock cycles/seconds and it is expressed as follows: CP U time = I * CP I * T where I is the number of instructions in program, CP I is the average cycles per instruction and T is the clock cycle time. Furthermore, CP I can be detailed as: CP I = CP Iexecution + CP Imemstall where CP Imemstall = M em accesses per instruction * M iss rate * M iss penalty. Therefore, CP U time becomes: CP U time = I * (CP Iexecution + CP Imemstall) * T.

  which is used in turn to define C-AMAT as expressed below:C -AM AT = Hit T ime C h * Hit Rate + M iss Rate * AM P C mwhere C h represents hit concurrency and C m represents miss concurrency.

Figure 2 :

 2 Figure 2: Big.LITTLE architecture

Figure 3 :

 3 Figure 3: Energy Delay Product

table :

 :

	Metric	Description
	CPU time	CPU execution time (cycles, seconds)
	Miss rate	Number of misses per total cache access
	Hit rate	Number of hits per total cache access
	Misses per instruction	Number of misses per instruction
	Number of cycles per instruction Time required for an instruction to be executed (cycles, sec-
		onds)
	Miss penalty	Number of cycles consumed while a cache miss occurs (cy-
		cles, seconds)
	Branch miss prediction rate	Frequency of untaken branches
	Average memory access time	Average latency to access a data (cycles, seconds)
	Access per cycle	Num. of memory accesses per cycle at certain level, e.g. L1
	Energy	Total energy consumption (Joules)
	Power	Energy per unit of time (Watts, Joules/second)
	Energy Delay Product	Figure of merit correlated with the energy efficiency
	Activity level at a given time	Number of instructions executed at a given point in time
	Resynchronization time	Time required for a resource to get back from sleep state to
		active state (cycles, seconds)
	Read/Write ratio	Read/Write ratio in a memory
	Number of stores	Number of write operations on a memory


S A S Cortus

Michael Chapman
email: michael.chapman@cortus.com

Erven Rohou
email: erven.rohou@inria.fr

Rue De Freyr

Project Partner Contact Information

While emerging non-volatile memories are a promising low power design solution for modern architectures, they suffer from high write-latency and energy consumption. This makes them less favorable for first level caches such as L1 cache, compared to usual SRAM memory. We propose a compiler-based approach to attenuate the cost of write operations in an architecture that integrates magnetic memory such as the Spin Transfer Torque Random Access Memory (STT-RAM) technology for L1 cache.

In this deliverable, we present an LLVM optimization to reduce the number of silent stores in memory (stores that have no impact because they write a value already present in memory at this location), therefore mitigating the number of write transactions on STT-RAM memory. We show our recent results that confirm the promising impact of this optimization on the energy consumption. We also analyze in details the impact of the application characteristics, the compiler and various microarchitectural features.

Please note that the contents of this deliverable is mainly based on the results published in conferences or journals by the consortium members of the CONTINUUM project. More technical details could be found in the corresponding references.

Introduction

Modern high performance Chip Multiprocessor (CMP) systems include large on-chip cache hierarchies, e.g., up to L3 level caches, as illustrated in Fig. 1. An important part of the overall energy consumption comes from the multi-level, on-chip cache hierarchy. In fact, as technology scales down, the leakage power in CMOS technology of the widely used SRAM-based cache gets increased, which degrades the system energy-efficiency. The memory system management techniques offer different ways to reduce their related power consumption. For instance, traditional memory technologies such as SDRAM have the ability to switch to lower power modes upon a given inactivity threshold. Further approaches rather applied to embedded systems, deal with memory organization and optimization [30] [3]. Their very low leakage power, makes them very good candidates for optimized energy consumption, as studied in both academia and industry [START_REF] Mittal | A survey of software techniques for using non-volatile memories for storage and main memory systems[END_REF]. Yet, NVMs are also suffering from their limited endurance, higher write latency and energy,compared to their counterpart SRAM. This makes NVMs a priori less favorable for write-intensive workloads. Therefore, a straightforward use of NVMs in place of SRAM would inevitably lead to a performance degradation and dynamic power increase that would in turn become energy-detrimental despite the leakage power saving.

NVM technologies have different performance, energy and endurance properties as shown in Fig. 2 from [START_REF] Zhao | Memory and storage system design with nonvolatile memory technologies[END_REF]. For instance, PCRAM and RRAM, have limited endurance that is much lower than SRAM and DRAM. However, with current technology, STT-RAM has an endurance similar to SRAM, making it conceivable to design cache hierarchies in non-volatile technologies, including the first level.

There are several works that studied the drawback of NVMs-based architectures using fully-hardware based mechanisms. The most common idea is to manage thoroughly the writes operations with the objective of reducing the number of writes activities on NVMs. Whence, hybrid memory systems where NVM is combined with other types, were rigorously been studied and several approaches were proposed, based on data placement and data migration from NVM to the other type of memory.

For compiler-oriented optimizations

We consider a compiler-based approach to mitigate the overhead of stores on STT-RAM-based cache. The role of the compiler is to present to the hardware a sequence of instructions that best exploits the underlying resources. Compilers, traditionally, are not directly exposed to energy aspects. However, with all the weight given to energy consumption, it is worthy to investigate how the compiler optimizations could have tremendous impacts on the overall energy consumption. As the main factor for activity on processor and memory systems, software has a signification effect on the energy consumption of the entire system. Still, developing new power-aware compiler optimizations and combine them with performance-oriented compiler optimizations is the focus of several researches.

As software execution corresponds to performing operations on hardware, as well as accessing and storing data, it requires power dissipation for computation, storage and communication. Beside the fact that the energy consumed during execution is very important, reducing the code size and thus, the storage cost of a program, is the classical goal of compilers. The energy cost of executing a program rely on the machine code and the target machine. Therefore, for a target architecture, energy cost is bound to machine code and consequently to compilation. Hence, it is the compilation process itself that strikes energy consumption.

Traditional optimizations on SRAM-based memories increase the performance of a program by reducing the work to be done during program execution [START_REF] Muchnick | Advanced Compiler Design and Implementation[END_REF][START_REF] Aho | Compilers: Principles, Techniques, and Tools[END_REF]. Memory optimizations play with latency and data placement. Optimizations such as loop tiling and register allocation try to keep data closer to the processor in order be accessed more faster. Memory optimizations contribute also in reducing energy consumption. Loop tiling tries to keep a value in an on-chip cache instead of an off-chip memory and register allocation optimization try to allocate data in a register instead of the cache. Both techniques allow to save power/energy due to reduced switching activities and switching capacitance [START_REF] Kremer | Low power/energy compiler optimizations[END_REF].

Our contribution

After a preliminary evaluation of typical optimizations found in mainstream compilers such as gcc or clang, we propose a new dedicated compiler-based approach [START_REF] Bouziane | LLVM-based silent stores optimization to reduce energy consumption on STT-RAM cache memory[END_REF][START_REF] Bouziane | How could compile-time program analysis help leveraging emerging nvm features?[END_REF][START_REF] Bouziane | Compile-time silent-store elimination for energy efficiency: an analytic evaluation for non-volatile cache memory[END_REF] to minimize energy consumption Version 2.0 (2017) Confidentiality: Public Distribution on STT-RAM based cache by mitigating the drawback of such a technology. Our approach aim to reduce the number of write operations by reducing the number of silent stores, which are the stores that write a value that already exist in memory. In a previous study [START_REF] Péneau | Loop optimization in presence of STT-MRAM caches: A study of performance-energy tradeoffs[END_REF], we explored the feasibility of integrating STT-RAM at different cache hierarchy levels in ARM architectures. Both L1 instruction and data caches were evaluated with SRAM and STT-RAM technologies. Based on the promising gained insights, we now apply the silent store transformation in presence of STT-RAM in L1 cache.

Outline

The rest of this document is organized as follows. The related works are presented in Section 3. Background information about silent stores and the implementation of the optimization is provided in Section 4. In section 5, a set of experiments is conducted to evaluate the proposed approach. In Section 6, we provide important insights to a better outcome. Finally, Section 7 concludes this report.

Related works

We briefly discuss some existing work on the exploitation of STT-RAM in the memory architecture. The STT-RAM integration in the system is coupled with either hardware-level or compiler-oriented optimizations. This enables to mitigate a major limitation of STT-RAM w.r.t its costly write access.

Hardware-based optimizations/scheduling

There are several works that studied energy efficiency on NVMs-based hybrid cache using fullyhardware based mechanisms [START_REF] Sun | A novel architecture of the 3d stacked MRAM L2 cache for cmps[END_REF][START_REF] Senni | Emerging non-volatile memory technologies exploration flow for processor architecture[END_REF][START_REF] Senni | Exploring MRAM technologies for energy efficient systems-on-chip[END_REF][START_REF] Senni | Emerging non-volatile memory technologies exploration flow for processor architecture[END_REF]. Sun et al. in [START_REF] Sun | A novel architecture of the 3d stacked MRAM L2 cache for cmps[END_REF] proposed hybrid L2 cache consisting of MRAM and SRAM, and employed migration based policy to mitigate the drawbacks of MRAM. The idea is to keep as many write intensive data in the SRAM part as possible to reduce the number of write operations to the STT-RAM part. They designed an SRAM-MRAM hybrid L2 cache with 31 ways of MRAM and 1 way of SRAM. Considering the high probability that a program writes data to a specific group of memory blocks repeatedly, data on MRAM should be migrated to SRAM if they are frequently written. Authors in [START_REF] Senni | Exploring MRAM technologies for energy efficient systems-on-chip[END_REF][START_REF] Senni | Emerging non-volatile memory technologies exploration flow for processor architecture[END_REF][START_REF] Senni | Emerging non-volatile memory technologies exploration flow for processor architecture[END_REF] proposed a methodology that combines the gem5 [START_REF] Binkert | The gem5 simulator[END_REF] and NVSim [START_REF] Dong | A circuit-level performance, energy, and area model for emerging nonvolatile memory[END_REF] simulators for assess the impact of STT-RAM integration at different cache levels. They explored the possible energy savings enabled by STT-RAM when integrated at both L1 and L2 cache levels.

Migration based techniques are widely recommended in recent works on hybrid caches [START_REF] Wu | Hybrid cache architecture with disparate memory technologies[END_REF][START_REF] Jadidi | High-endurance and performance-efficient design of hybrid cache architecture through adaptive line replacement[END_REF][START_REF] Li | STT-RAM based energy-efficiency hybrid cache for cmps[END_REF]. Li et al. in [START_REF] Li | STT-RAM based energy-efficiency hybrid cache for cmps[END_REF] proposed a migration mechanism to handle read operations also. Memory blocks that are read frequently are migrated from SRAM into STT-RAM. Zhou et al. in [START_REF] Zhou | Energy reduction for STT-RAM using early write termination[END_REF] proposed a technique called Early Write Termination to significantly reduce write energy with no performance penalty. It is a write process with the capability of early termination in case of a redundant write. It is implemented at the circuit level and dos not require extra read to precede a write, hence, the implementation does not have any impact on performance. [START_REF] Smullen | Relaxing non-volatility for fast and energy-efficient stt-ram caches[END_REF] proposed an approach for redesigning STT-RAM memory cells to reduce the high dynamic energy and slow write latencies. They lower the non-volatility time and as a result of that, the write current is reduced. Chen et al. in [START_REF] Chen | Dynamically reconfigurable hybrid cache: An energy-efficient last-level cache design[END_REF] proposed a reconfigurable hybrid cache architecture , in which NVM is put in the last-level cache along with SRAM. They provide hardware-based mechanisms to dynamically reconfigure hybrid cache based on the cache demand. They introduced a power gating circuitry to allow powering on/off SRAM/NVM arrays at way level.

Smullen et al. in

Hu et al. in [START_REF] Hu | Reducing write activities on non-volatile memories in embedded cmps via data migration and recomputation[END_REF] targeted embedded Chip Multiprocessors (CMPs) with ScratchPad Memory (SPM) and non-volatile main memory. They introduced data migration and recomputation techniques to reduce the number of write activities on non-volatile memories In data migration, data is stored temporarily on the SPM of other cores rather than written back to the main memory. In data recomputation, the number of write activities is reduced by discarding the data that should have been written back to the main memory and recomputing it when it is needed.

Compiler-based optimizations

To explore the advantages of the hybrid cache, migration-based techniques are commonly used to dynamically move/migrate write-intensive data from STT-RAM to SRAM. Yet, migrations require additional read and write operations for data movement and this overhead has an impact on the performance and the energy efficiency of STT-RAM based hybrid cache. Li et al. in [START_REF] Li | Code motion for migration minimization in stt-ram based hybrid cache[END_REF] addressed this issue and proposed a compilation method called migration-aware code motion. This mechanism is conceived to change the data access patterns in memory blocks in order to minimize the overhead of migrations . It consists of scheduling instructions accessing the same memory block with the same operation close to each other.It is designed without any hardware modification. Li et al. in [START_REF] Li | Migration-aware compilation for stt-ram based hybrid cache in embedded systems[END_REF] also proposed a migration-aware compilation for STT-RAM based hybrid cache in embedded systems, by re-arranging data layout to reduce the number of migrations. They showed that the reduction of migration overheads improves energy efficiency and performance. They also presented in [START_REF] Li | Compiler-assisted preferred caching for embedded systems with stt-ram based hybrid cache[END_REF] a migration-aware cache locking approach to reduce the migrations by locking migration-intensive memory blocks into SRAM part of hybrid cache.

Li et al. in [START_REF] Li | Multiple graph-coloring for nonvolatile memory based hybrid scratchpad memory[END_REF] targeted the problem of allocating program variables into hybrid SPM-based systems. They presented an ILP formulation exploring that variables that are not alive simultaneously can share the same memory address and a graph-coloring based polynomial-time algorithm to address the problem of hybrid SPM allocation.

Hu et al. in [START_REF] Hu | Data allocation optimization for hybrid scratch pad memory with SRAM and nonvolatile memory[END_REF] presented an approach based on region partitioning to generate optimal data allocations for each region. The program is divided into regions and before starting the execution of each region, data management code is executed to generate a data allocation which is suitable for this region.

Current work

In this work, we consider a compile-time optimization consisting in eliminating redundant write accesses to non hybrid L1 cache memory designed with STT-RAM, while improving energy-efficiency. We adopt the so-called silent store elimination technique introduced by Lepak et al. [START_REF] Lepak | On the value locality of store instructions[END_REF], who presented two store squashing mechanisms at microarchitectural level, called realistic and perfect. The realistic mechanism consists in replacing all stores by a store verification, which is a load, a comparison and the store if it is not silent. The perfect mechanism follows a similar principle, while the verification is performed only for the stores that are already known to be silent. Here, we leverage the realistic mechanism at compiler level for portability and more flexibility contrarily to the hardware-oriented approaches found in literature A store is said to be silent if it writes a value to a memory address where the same value is already stored.

Silent-store have been initially proposed and studied by Lepak et al. in [START_REF] Lepak | Silent stores and store value locality[END_REF] where they suggested new techniques for aligning cache coherence protocols and microarchitectural store handling techniques to exploit the value locality of stores. Their studies showed that eliminating silent stores helps to improve uniprocessor speedup and reduce multiprocessor data bus traffic.

Previous work showed that there is a significant percentage of total silent stores. Bell et al. [START_REF] Bell | Characterization of silent stores[END_REF] outline 18 % to 64 % of total stores as silent for SPEC95 benchmarks. In our study, we choose to move the concept to the compiler level, and use a similar mechanism for silent stores detection and elimination to reduce the energy consumption of on STT-RAM-based architectures.

The initial proposal was devised in hardware, and different mechanisms for store squashing have been proposed. In this work, we propose a software approach which is good for portability, and requires no change to the hardware. Our approach consists of modifying the source code by inserting silentness verification before stores that are identified as silent (see Figure 3). The intuition behind this approach is to reduce the total number of writes by replacing silent stores by loads.The stores verification helps to check whether the identified stores are indeed silent during their execution. This implementation is a realistic implementation. An ideal implementation would be to execute one time the identified silent stores and avoid verifying them, assuming that the identified stores will be always silent. The verification process is composed of a load to store address, a comparison of the loaded value with the to-be stored value and a conditional branch. The store will eventually not be executed if the verification is satisfied. Not all stores are silent, and stores may not be silent all the time. Still, silent stores can be characterized to some extent. Our solution attempts to optimistically replace a store by a sequence of instructions that avoids it. Whenever the store happens to not be silent, it must be executed. This case incurs a penalty, which we want to minimize. The process of identifying the stores that are silent is explained later on.

LLVM-based implementation

In order to apply the silent stores reduction, we implemented an LLVM-based optimization. The compilation framework is composed of two steps as follows:

• Step 1: Silent store profiling, based on memory profiling, collects information on all store operations to identify the silent ones;

• Step 2: Apply the optimization pass on the stores that are silent.

Our compilation process is a front-end framework. We focused on the intermediate representation (IR) as shown in Figure 4, where we implemented the silent stores optimization. While this figure describes a generic decomposition into basic steps, its instantiation in our case only contains two "Passes" (see above) between the IR boxes.

Through the first step, we want to get information about all the store instructions that are in a program.

For that, we insert new instructions in the IR in front of every store to check whether the stored valued is equal to the already stored value. If it is the case, we increment a counter related to this particular store. Once the first step is done, we obtain a summary reporting how many times the store addresses have been accessed and how many times they have been silent. We also save their positions in the program so that we can identify them in the next step. Then, we move to the second step, where we apply the main part of the optimization taking into account the profitability threshold,. Hence, we apply the transformation only for stores that are likely to be more than 65% silent. We insert before every silent store that we identified from the previous step, the following instructions:

1. a load instruction to the store address;

2. a comparison instruction, to compare the written value to the already stored value;

3. a conditional branch instruction.

The objective is to execute the store instruction only if it is not silent as shown in Figure 3. The first step allows us to avoid inserting the checking instructions before all store instructions to minimize the possible overhead related to checks. The trad-off is between the cost of a write operation and the cost of a load, a compare and a conditional branch, in terms of time and energy. For each candidate Page 8 Version 2.0 (2017) Confidentiality: Public Distribution store, the transformation replaces the store by a sequence of load-compare-branch, and possibly a store (when not silent).

Since we're targeting ARM architectures, we take benefit from conditional instructions and particularly the conditional store strne. Therefore, the transformed store will be as showed in the Figure 5. Note that Thumb extension does not provide predication. Using ARM ISA allows us to minimize the number of inserted instructions and therefore the impact of the transformation on performance: instead of inserting three instructions, we insert only two.

Motivational example

As a motivational example, we analyze the possible impact of memory on the energy consumed by an on-chip system. For the sake of simplicity, we consider a simple on-chip system model comprising a CPU, an L1 data denoted by L1d, an L1 instruction cache denoted by L1i, a bus and a memory controller. No other cache level (e.g. L2 or L3 cache) is taken into account, while the main memory is off-chip.

To design and evaluate this model, we use a number of simulation and power modeling tools already integrated in the MAGPIE automated design evaluation framework [START_REF] Delobelle | System-level Evaluation of Manycore Systems with Emerging Memory Technologies[END_REF][START_REF] Delobelle | Flot automatique d'évaluation pour l'exploration d'architectures à base de mémoires non volatiles[END_REF][START_REF] Senni | Embedded systems to high performance computing using stt-mram[END_REF]. These tools include the gem5 [START_REF] Binkert | The gem5 simulator[END_REF] cycle-approximate simulator, combined with the NVSim [START_REF] Dong | A circuit-level performance, energy, and area model for emerging nonvolatile memory[END_REF] and McPAT [START_REF] Li | An integrated power, area, and timing modeling framework for multicore and manycore architectures[END_REF] power, area and latency modeling tools, which respectively target non volatile and CMOS technologies. Here, the gem5 minor CPU model is used to define an ARM Cortex-A7 core running at 1 GHz, associated with L1i and L1d caches, both 32 KB and 4-way associative [START_REF] Butko | Fullsystem simulation of big.little multicore architecture for performance and energy exploration[END_REF].

In order to assess the possible gain that one could expect from different memory technology candidates, we consider a simple program P illustrated in Fig. 6 (C and assembly codes). Since we are focusing on store instructions, we decided to carry out a preliminary experimental analysis on such a dedicated kernel with different execution scenarios. This simple code shows one store operation that is executed N times. We identify this store as a silent store.

Let us evaluate the cost of this simple code on a Cortex-A7 in terms of execution time, energy consumption and energy-delay product (EDP). In this work, EDP is considered as the main figure of merit for energy-efficiency as it combines both execution time and energy. By executing 50 million iterations of the simple program (i.e., N = 50 × 10 6 ), we obtain the result reported in observe a reduction of the energy consumption thanks to the low static power inherent to the used non volatile memory. A very marginal increase is observed in the execution time, which is due to the penalty expected from higher write latency of STT-RAM compared to SRAM. Fortunately, this marginal increase is not important enough to cancel the gain in static power enabled by STT-RAM. As a result the EDP is improved. Fig. 7 shows the application of the transformation on P. In Table 2, after transformation, we see how the number of instructions increases by approximately 100 million instructions, that correspond to 50 million load instructions and 50 million compare instructions. The number of cycles and the execution time did not increase, which means that the transformation on this small program didn't have an impact on performance. The key point is not to increase the total execution time, because leakage is proportional to time. Since the core represents a significant fraction of the total power, a slight increase is likely to offset the gain of the cache alone. Note that the reported results correspond to a scenario where the store is always silent, which means it's 100% silent.

Profitability Threshold

From the point of view of the data cache (considered in isolation), the optimization transforms a write into a read, possibly followed by a write. The write must occur when the store happens to not be silent.

In the most profitable case, we replace a write by a read, which is beneficial due to the asymmetry of STT-RAM. On the contrary, a never-silent store results in write being replaced by a read and a write. Thus, the profitability threshold depends on the actual costs of memory accesses. In terms of energy cost we want:

α read + (1 -P silent ) × α write ≤ α write
where α X denotes the cost of the operation X and P silent is the probability of this store to be silent. This is equivalent to:

P silent ≥ α read α write
Given the values of Table 3, we obtain a threshold of:

P silent ≥ 109/174 ≈ 0.63, i.e., a silentness percentage of 63 %.

The above reasoning only considers cache memory accesses, and holds as long as the rest of computations does not heavily impact the system energy consumption compared to those cache memory accesses. We confirm it experimentally by considering the simple program shown in Fig. 8, where N represents the total number of store operations and M represents the number of silent instances/occurrence. We run the program with different values of M , so as to vary the silentness percentage. In Fig. 8, we observe, as expected, that higher probability of silentness reduces energy consumption of the L1 data cache. The silent store elimination is beneficial when the silentness percentage is above 63 %. 5 Experimental setup

Configuration

We consider a simple ARM monocore architecture based on Cortex-A7. We use an evaluation framework called MAGPIE [START_REF] Delobelle | System-level Evaluation of Manycore Systems with Emerging Memory Technologies[END_REF], consisting of the gem5 simulator, combined with the NVSim and McPAT timing, power and area estimation tools (based on gem5 stats), see Figure 9. NVSim specifically target NVMs technologies. In our case, the STT-RAM technology is used. In a previous study [START_REF] Péneau | Loop optimization in presence of STT-MRAM caches: A study of performance-energy tradeoffs[END_REF], we explored the feasibility of integrating STT-RAM at different cache hierarchy levels in ARM architectures. Both L1 instruction and data caches were evaluated with SRAM and STT-RAM technologies. Based on the promising gained insights, we now apply the silent store transformation in presence of STT-RAM in L1 cache. can be transformed in order to improve the energy-efficiency with STT-RAM. This is visible in Table 4, where the STTRAM+opt scenario shows better results than STTRAM scenario, in terms of execution time and total energy consumption. The reported results in Table 4 corresponds to small inputs.

For the remaining applications, i.e., heartwall, pathfinder, srad, particlefilter, nw and kmeans, the silentness percentages of identified silent stores vary from 1 % to 100 %. Note that the maximum percentage for nw is 50%. Only the two silent stores corresponding to this percentage are optimized for profitability reason. All other applications are optimized by transforming their silent stores associated with at least 63% of silentness percentage. Table 4 summarizes the evaluation of all these optimizations. We carried out further investigations by evaluating the above applications while optimizing silent stores associated with at least an arbitrary silentness percentage of 15%. For most of the applications, no gain was observed except for kmeans and pathfinder.

For these two applications, the gain is as good as with 63%. This suggests the profitability threshold of kmeans and pathfinder can be around 15%. In order to understand how the optimization profitability threshold varies from an application to another, the number of store instances could be analyzed. For kmeans, this number associated with low silentness percentage, e.g. 15%, is negligible compared to the number of store instances associated with higher silentness percentages, e.g. 63%. Therefore, the overhead introduced by the optimization of stores with low silentness percentage is marginal enough to be mitigated globally. This explains the similar evaluation results observed with 15% and 63% thresholds for the two applications. However, in the other applications, the number of store instances associated with low silentness percentage is significant enough to induce a penalizing overhead resulting from our optimization of stores. Then, this translates into higher execution time and energy.

Analysis of optimization applicability

Executing instructions does not necessarily increase total execution time due to the synergy of compiler optimizations with several micro-architectural features of modern processors, as well as properties of applications. Many factors are involved in the impact of the presented optimization. The compiler itself and the architectural features play an important role. Compiler Scheduler orders instructions so that the resulting sequence minimizes the execution time. The compiler is free to swap instructions as long as they do not have any dependencies. The goal is then to maximize the utilization of hardware resources, yet avoid over-subscription. Scheduling is key for an in-order cores. Out-Of-Order cores are less sensitive since they have hardware mechanisms to generate a schedule at runtime, though they have a much more limited visibility on upcoming instructions. Architectural features have significant impact on compiler optimizations. In our case, since we led experiments on ARM cores, particularly cortex-A7, that supports ARM ISA as well as Thumb ISA, we found out that the difference between these two ISA can make an important change in the direction of this study. In fact, Thumb ISA does not support conditional instructions. Thus, strne will be automatically converted to a branch+str. For that, we studied the cost of the transformation with the branch as shown in the Figure 11. Then, we observed that the number of cycles increases significantly due to the branch which make us conclude that we take more benefit from this optimization by using ARM ISA where we have one fewer instruction, thus limiting the risk to increase execution time. As a side effect, it also lowers the number of branch mispredictions by eliminating the branch alltogether. Hence, if we use this transformation under Thumb, the overhead of branch instructions must be concealed in order to see the optimization effect. Moreover, superscalar processors can execute several independent instructions in parallel. For example, the ARM Cortex A7 is a dual-issue processor. In many cases, the processor is not able to fully exploit the available parallelism, leaving empty slots. When added instructions are able to fit in these unexploited slots, they do not increase execution time. Consider the example on Figure 12: in the original code, each instruction depends on its predecessor. Execution is purely sequential, even on a superscalalr processor. Our newly introduced instructions can be executed in the empty slots, as shown on the the right hand side of the figure. Note that the independent subtractions has been scheduled earlier to maximize overlap. Therefore, our silent stores elimination technique works best if we can hide the newly introduced instructions in empty slots. This requires superscalar capability. We rely on the compiler to schedule this instructions at the best possible locations in the original sequence of instructions. This is critical for in-order processors. OoO processors may be able to find an optimal sequence by themselves, but OoO also generates a denser schedule, with fewer empty slots. In order to assess the possible gain that one could expect from the transformation, the program should be analyzed before applying the silent stores transformation. If the instructions scheduling doesn't allow to hide the silentness verification, then the overhead of this verification will increase the execution time and therefore the total leakage.

Conclusion and perspectives

In this study, we presented how the implementation of a typical compiler optimization can contribute in mitigating the dynamic energy consumption issue related to NVMs at L1 cache level. This optimization eliminates silent stores in cache accesses, which in turn reduces the number of write transactions that are more expensive than read ones for NVMs, both in terms of latency and energy consumption. It has been fully implemented in LLVM and validated on a subset of Rodinia benchmark. Beyond the L1 cache illustrated in this work, this optimization is also beneficial to any memory hierarchy level integrating NVMs. From the previous analysis, a successful application of our compiler-level optimization requires a number of features for a better outcome. It provides better energy-efficiency results when the cost of newly introduced instructions can be hidden adequately. This requires superscalar capability for exploiting empty instruction slots. We also rely on the compiler to schedule these instructions at the most suitable locations in the original sequence of instructions. This is critical for in-order cores, while OoO cores are able to find an optimal sequence by themselves. The use of predicated instructions is another interesting feature that enables to mitigate the possible execution time overhead related by the extra instructions introduced by our optimization.

An extension of this work would be to automatize the program analysis phase for silent stores verification, thus, making the compilation process on three steps instead of two: detecting silent stores with the profitability threshold, analayze instructions schedulability and then apply the transformation except and only on the stores where the verification instructions will be covered by the parallelism of the execution.

2. 1

 1 For compiler-oriented optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Our contribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Related works 3.1 Hardware-based optimizations/scheduling . . . . . . . . . . . . . . . . . . . . . . . 3.2 Compiler-based optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Current work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Silent stores optimization 4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 LLVM-based implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Motivational example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 Profitability Threshold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Experimental setup 5.1 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Experiments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Figure 1 :

 1 Figure 1: Memory hierarchy model

Figure 2 :

 2 Figure 2: Comparison of traditional memory and NVM technologies[START_REF] Zhao | Memory and storage system design with nonvolatile memory technologies[END_REF]

Figure 3 :

 3 Figure 3: Silent store transformation

Figure 4 :

 4 Figure 4: LLVM architecture

Figure 5 :

 5 Figure 5: Transformation with conditional store

(Figure 6 :

 6 Figure 6: Dedicated kernel. The volatile keyword forces the compiler to keep the memory access on x, while other variables may be promoted to registers. The assignment in the loop repeatedly writes the same value 0 to the same memory location

D2. 2 -Figure 7 :

 27 Figure 7: Transformation on P (see Fig. 6)

Figure 8 :

 8 Figure 8: Determination of the profitability threshold of silent store elimination.

Figure 9 :

 9 Figure 9: The simulation flow : MAGPIE

Figure 11 :

 11 Figure 11: Transformation without prediction P (see Fig. 6)

add r 1 =

 1 r 2 + r 3 add r 4 = r 1 +2 mul r 5 = r 4 * r 3 add r 6 = r 5 +3 s t o r e @x= r 6 sub r 4 = r2-r 3 sub r 5 = r4 -1 . . . 1 add r 1 = r 2 + r 3 | | l o a d r 0 =@val 2 add r 4 = r 1 +2 3 mul r 5 = r 4 * r 3 4 add r 6 = r 5 +3 5 sub r 4 = r2-r 3 | | cmp r6 , r 0 6 sub r 5 = r4 -1 | | beq n e x t 7 s t o r e @x= r 6 8 n e x t : 9 . . .

Figure 12 :

 12 Figure 12: Example of superscalar execution. The original code (left) is purely sequential, the transformed code is able to take advantage of unexploited parallelism

7

 7

Table of Contents

 of

	1 Summary
	2 Introduction

Table 1

 1

	and

Now, by re-executing the same program while considering the L1 cache is entirely in STT-RAM instead of SRAM, we obtain the result displayed in Table

1

, referred to as "full-STTRAM". Here, we

Table 1 :

 1 Evaluations of dedicated kernel: execution of original code with full SRAM L1 cache (ref.); execution of original and optimized codes with full STT-RAM L1 cache.

		Exec. time (ms) Energy (mJ)	EDP
	full-SRAM (ref)	305.13	79.5 24257.83
	full-STTRAM	305.31	67.8 20700.01
		(+0.06 %)	(-14.7 %)
	full-STTRAM	305.31	64.6 19723.02
	+ silent store opt	(+0.06 %)	(-18.7 %)

Table 2 :

 2 Some relevant metrics about the execution of P before and after silent stores transformation

	Metric	Before transformation After transformation
	Execution time	305.31	305.31
	Number of instructions	201 222 222	301 223 106
	Number of cycles	305 304 382	305 312 970
	Page 10	Version 2.0
		(2017)
	Confidentiality: Public Distribution

Table 3 :

 3 32 KB SRAM and STT-RAM memory estimation with NVSim

	Technology	Latency	Dynamic Energy Leakage
		Read Write Read	Write
		(ns)	(ns)	(pJ)	(pJ)	(mW)
	SRAM	1.31	1.19	24	6	44.70
	STT-RAM 1.96 10.94	109	174	6.72
			Version 2.0
			(2017)
		Confidentiality: Public Distribution

Table 4 :

 4 Optimizing sample applications: SRAM and STTRAM configurations denote the original application program executed respectively with full SRAM and full STT-RAM L1 caches; STTRAM+opt denotes the code optimized for stores above the indicated silentness percentages and executed with full STT-RAM L1 caches.

	App.	Config.	Exec. time Energy	EDP
			(ms)	(mJ)
	backprop	SRAM	598.5	136.1	81455.85
		STTRAM	636.6	124.5	79256.70
		STTRAM+opt	621.7	122.1	75909.57
	heartwall	SRAM	13399.6	3269.3 43807312.28
		STTRAM	13855.0	2773.0	38419915
		STTRAM+opt	13818.4	2764.1 38195439.44
	pathfinder	SRAM	137.2	35.9	4925.48
		STTRAM	137.8	30.1	4147.78
		STTRAM+opt	137.6	30.1	4141.76
	srad	SRAM	8154.8	1693.7 13811784.76
		STTRAM	8230 1479.50	12176285
		STTRAM+opt	8214.2	1476.8 12130730.56
	particlefilter	SRAM	11255.83	2424.8 27293136.58
		STTRAM	11464.2	2133	24453138.6
		STTRAM+opt	11455.84 2132.10 24424996.46
	nw	SRAM	440.3	100.8	44382.24
		STTRAM	455.73	88.6	40377.68
		STTRAM+opt	452.6	88.1	39874.06
	kmeans	SRAM	118.11	28.1	3318.89
		STTRAM	126.5	24.9	3149.85
		STTRAM+opt	108.11	21.7	2345.99

Experiments

In their seminal work [START_REF] Lepak | On the value locality of store instructions[END_REF], Lepak and Lipasti studied the SPEC95 benchmark suite in which high silentness percentages have been exposed. For instance, vortex and m88ksim reach respectively 64 % and 68 % of silent stores overall on PowerPC architecture (there was no per-store characterization in that paper). Such silentness levels could typically benefit from our optimization. More generally, the profitability threshold of our optimization for an application depends on the silentness distribution over its store instructions. Higher silentness percentages of these instructions favor more energy reduction. In order to explore this trade-off, let us consider a subset of applications defined in the Rodinia benchmark suite [START_REF] Che | A characterization of the rodinia benchmark suite with comparison to contemporary CMP workloads[END_REF]: backprop , heartwall, pathfinder, srad, particlefilter, nw and kmeans. Fig. 10 summarizes a silentness analysis of their store instructions: they respectively contain 3 silent stores (i.e., silent at least once) out of 17 stores, 13 silent stores out of 99 stores, 9 silent stores out of 28 stores, 8 silent stores out of 29 stores, 3 silent stores out of 53 stores, 4 silent stores out of 18 stores and 8 silent stores out of 15 stores. The silentness distribution over these silent stores is reported in Fig. 10 via the displayed percentages. For instance, for backprop all 3 silent stores are highly silent: one at 94 % and two at 100 %, meaning that they