Abstract:
The invention relates to a method for updating a variable shared between multiple processor cores. The following steps are implemented during execution in one of the cores of a local scope atomic read-modify-write instruction (AFA), having a memory address (a1) of the shared variable as a parameter: performing operations of the atomic instruction in a cache line (L(a1)) allocated to the memory address; and locally locking the cache line (LCK) while authorizing access to the shared variable by cores connected to another cache memory of same level during execution of the local scope atomic instruction.

Description:
FIELD 
       [0001]    The present disclosure relates to read-modify-write atomic instructions implemented by a multi-core processor having a shared cache memory, usually a cache memory of level-2 or greater. 
       BACKGROUND 
       [0002]      FIG. 1  is a simplified diagram of a four-core processor connected to a system memory MEM, typically a dynamic memory DDR, through two levels of cache memories. Each processor core CPU has its own level-1 cache memory L1. Each pair of cores shares a level-2 cache memory L2. Finally, each cache memory L2 shares access to the system memory MEM. Some processors may have a level-3 cache memory shared between the cache memories L2. 
         [0003]    Each cache memory includes a controller CTRL for performing the operations carried out in the cache memory, including ensuring coherence (co) between the cache memories. The processor cores generally operate on virtual addresses, whereas cache memories operate with physical addresses. A memory management unit MMU is thus usually provided between each processor core and the associated controller CTRL for translating the virtual addresses into physical addresses. 
         [0004]    In such processors, there may be a need for sharing data between portions of code, or program threads, executed on different cores, which introduces a challenge bearing in mind the multiple cache memories interposed between the cores, which may store different versions of the shared data. 
         [0005]    To ensure reliable sharing of data between the multiple cores, read-modify-write atomic instructions are often used, for example the so-called Fetch-and-Add (FA) or Compare-And-Swap (CAS) instructions. A feature of these instructions is that they produce an effect perceived as instantaneous on the content of the system memory. In other words, the various operations composing each atomic instruction, often the reading of a variable, the modification of the variable, and writing back the variable, are executed while guaranteeing the absence of external interference on the variable between reading and writing back. 
         [0006]    To guarantee atomicity, a first technique is based on locking the system memory, preventing any access to the memory, or to a memory area, by other processes, even if these processes do not access the variable targeted by the read-modify-write sequence. 
         [0007]    Another technique is based on a cache coherence protocol by which a cache line containing the variable targeted by the atomic instruction is acquired in “exclusive” mode by the core executing the instruction. This acquisition causes invalidation of the cache line in the other cache memories, preventing the other cores from accessing the cache line, hence the corresponding memory area of the system memory, until the exclusive mode is raised by the core having acquired it. 
         [0008]    This technique limits access restrictions to only the memory area corresponding to the cache line, but it is complex to implement and produces data alignment constraints. 
         [0009]    The two techniques yield a common result of temporarily preventing access to the shared variable in memory, one using a mechanism implemented at the system memory level, the other using a mechanism implemented at the cache memory level. 
       SUMMARY 
       [0010]    A multi-core processor is generally provided, comprising a cache memory shared by a group of several cores configured to delegate atomic instructions to the cache memory; in its instruction set, an atomic read-modify-write instruction, taking as a parameter a memory address of a shared variable, wherein the atomic instruction can have a global scope; a cache memory controller configured for receiving and processing each global atomic instruction executed by a given core of the group by globally locking an address space containing the address of the shared variable, to prevent access to the shared variable by any other core during execution of the global atomic instruction. The atomic instruction can also have a local scope, the cache memory controller being configured for processing each local atomic instruction executed by a given core of the group by locally locking a cache line allocated to the address of the shared variable, while authorizing access to the shared variable to cores connected to another cache memory of same level during execution of the local atomic instruction. 
         [0011]    The cache memory controller may be configured for using a cache coherence protocol for implementing the global atomic instructions, and for, during execution of a local atomic instruction, locally locking the cache line without invalidating nor locking an analogous cache line in the other cache memory of same-level. 
         [0012]    The cache memory controller may alternatively be configured for locking a system memory area containing the shared variable during execution of a global atomic instruction, and for, during execution of a local atomic instruction, accessing the variable in the cache line without locking any area of the system memory. 
         [0013]    The global and local scopes of the atomic instructions may be implemented by two respective dedicated instructions of the processor instruction set. 
         [0014]    Alternatively, the global and local scopes of the atomic instructions may be implemented by a same instruction of the processor instruction set, and be differentiated by using two distinct virtual address spaces assigned to a same physical address space containing the shared variable, the processor including a memory management unit for performing virtual to physical address translations, and which assigns an “uncached” attribute to the virtual address space associated to the global scope. 
         [0015]    The local atomic instruction may be a fetch-and-add instruction, having as an additional parameter an increment value, and the cache controller may be configured to add the increment to the variable. 
         [0016]    A method is also provided for updating a variable shared between multiple processor cores, comprising the following steps implemented during execution in one of the cores of a local scope atomic read-modify-write instruction, having a memory address of the shared variable as a parameter: performing operations of the atomic instruction in a cache line allocated to the memory address; and locally locking the cache line while authorizing access to the shared variable by cores connected to another cache memory of same level during execution of the local scope atomic instruction. 
         [0017]    The method may comprise the step of locking the cache line without invalidating nor locking an analogous cache line in other cache memories of same level. 
         [0018]    The method may comprise the steps of defining the local scope of the atomic instruction through the execution of a dedicated instruction of the processor instruction set; and including a dedicated atomic instruction of global scope in the processor instruction set. 
         [0019]    The method may alternatively comprise the steps of translating a physical address space containing the shared variable from first and second distinct virtual address spaces through a memory management unit; assigning an “uncached” attribute to the second virtual address space; executing a generic atomic instruction with the first virtual address space for obtaining a local scope; and executing the same generic atomic instruction with the second virtual address space for obtaining a global scope. 
     
    
     
       BRIEF DESCRIPTION OF DRAWINGS 
         [0020]    Other advantages and features will become more clearly apparent from the following description of particular embodiments of the invention provided for exemplary purposes only and represented in the appended drawings, in which: 
           [0021]      FIG. 1 , previously described, is a simplified diagram of a four-core processor having two levels of cache memories; 
           [0022]      FIG. 2  is a time diagram illustrating an implementation of a conventional atomic fetch-and-add instruction, having a global scope; and 
           [0023]      FIG. 3  is a time diagram illustrating an implementation of an atomic fetch-and-add instruction having a local scope. 
       
    
    
     DESCRIPTION OF EMBODIMENTS 
       [0024]      FIG. 2  illustrates, through a time diagram, an implementation of a conventional atomic fetch-and-add instruction, as an example, in a system of the type of  FIG. 1 , using the conventional system memory locking method disclosed above. The instruction is designated “Atomic Fetch-and-Add Uncached” or AFAU, “uncached” meaning that the instruction is effective at the level of the system memory MEM. Such an instruction takes as parameters the address of the shared variable and the increment to add to it. The instruction stalls the core to wait for an acknowledgement, for example the return of the value of the shared variable, before modification. 
         [0025]    At a time t 0 , a core CPUa executes the instruction AFAU a1, i, where parameter a1 is the address of the shared variable and parameter i is the increment to add to it. The atomic instructions may be delegated to one of the cache memories, for example the nearest to the system memory, L2, whose controller may include a processing unit PU designed to implement the operations. 
         [0026]    Hence, at time t 0 , the atomic instruction is transmitted to cache memory L1, who transmits it in turn, at time t 1 , to cache memory L2. 
         [0027]    At a time t 2 , in response to the atomic instruction, the cache memory L2 executes a LoaD Uncached command LDU at address a1, which command is combined with a command LCK for locking the memory area containing the address a1. The memory MEM responds by locking the area, meaning that from time t 2  access to the memory area is reserved exclusively to the core CPUa having executed the atomic instruction. The interval during which the memory area is locked is shown by a bold line. 
         [0028]    Moreover, the execution of such an uncached command may trigger the coherence mechanism of the cache memories, for instance by invalidating the cache line allocated to the address a1 in all the cache memories (INVAL a1). Hence, another core that attempts to read the variable causes its cache memory to refresh with the updated variable from the system memory. If such an access occurs while the memory area is locked, the core is stalled until the memory area is unlocked. 
         [0029]    At a time t 3 , in response to the load command LDU, the memory returns the value val of the variable stored at the address a1. A relatively large number of clock cycles may elapse between the execution of the command LDU and the return of the value val. 
         [0030]    At a time t 4 , the cache memory L2 transmits the read value val to the cache memory L1 and locally adds the increment i to the value val. 
         [0031]    At a time t 5 , the cache memory L1 transmits the read value val to the core CPUa while cache memory L2 executes a STore Uncached command STU for storing the modified value of the variable at address a1, which command is combined with a command ULCK for unlocking the memory area containing address a1. 
         [0032]    At a time t 6 , in response to command STU, the system memory transmits to the cache memory L2 an acknowledgement signal ACK indicating that the memory area is unlocked. A relatively large number of clock cycles may elapse between the execution of the command STU and the transmission of the acknowledgement signal ACK. The system memory thus unlocks the memory area containing address a1. 
         [0033]    From time t 6 , the other cores may access the updated shared variable in the system memory. If another core has requested read access to the shared variable between times t 2  and t 6 , the variable is retrieved only from time t 6 . 
         [0034]    The effects of the commands LDU and STU executed in the cache memory L2, more precisely by the cache controller, may be similar to the responses of the cache memory to instructions of similar names executed by the core. This means that the cache line allocated to the address a1 is updated by these instructions. Hence, after execution of the store command STU, the cache line is up to date with the current value in memory of the variable. 
         [0035]    The system memory lock duration, shown by a bold line, may be relatively long, since the latency of the system memory may be expressed in hundreds of core clock cycles. This latency occurs twice for each atomic instruction, a first time for the load command LDU, and a second time for the store command STU. While the system memory is locked, no other process has access thereto and is stalled, even if the process does not access the shared variable. The memory may be partially locked, for instance by memory banks, but such areas remain relatively large, so that their locking is detrimental to system performance. 
         [0036]    In processors of the type of  FIG. 1 , cache memories may be shared between multiple cores, for instance two or four cores for a level-2 cache memory. Some processors may have a level-3 cache memory that can be shared by even more cores. Moreover, in many situations, the allocation of program threads to cores may be customized so that interdepending threads are allocated to cores sharing a same cache memory. For instance, in  FIG. 1 , two interdependent threads would be allocated respectively to cores CPUa and CPUb, or CPUc and CPUd. 
         [0037]    In addition, a variable shared by a group of interdependent threads generally has no utility for other processes, especially processes that may be executed on cores that do not share the cache memory. In other words, the other processes do not require access to an up-to-date value of the shared variable. 
         [0038]    On the basis of these findings, it is proposed herein to introduce atomic instructions having a local scope in the instruction set of the processor. More specifically, such an instruction is atomic only up to an intermediate cache level. In a processor including several levels of shared cache memories, it is preferred to attribute the local scope atomic instruction to the shared cache memory closest to the cores. 
         [0039]    The processor instruction set may include, in addition to a family of conventional atomic instructions (that will be qualified hereinafter as having a global scope), a family of analogous atomic instructions having a local scope. Thus, for instance, if the processor includes a conventional atomic fetch-and-add uncached instruction AFAU, the instruction set may be augmented by an analogous local scope or “cached” atomic instruction AFA. 
         [0040]    Then, conventional, global atomic instructions may be used in interdependent threads executed on any combination of cores that do not necessarily share the same cache memory, while new, local atomic instructions may be used in interdependent threads that are executed on cores that share a cache memory. 
         [0041]      FIG. 3  is a time diagram illustrating an exemplary implementation of a local atomic fetch-and-add instruction in the context of the processor example of  FIG. 1 . In the processor of  FIG. 1 , the shared cache memory closest to the cores is that of level-2 (L2). The local atomic instructions may then be attributed to the cache memories L2, whose controller may be configured to process them. 
         [0042]    At a time to, the core CPUa executes an instruction AFA a1, i, where parameter a1 is the address of the shared variable and i is the increment to add thereto. The instruction is attributed to the shared cache memory closest to the cores, L2. 
         [0043]    Thus, at time t 0 , the atomic instruction is transmitted to cache memory L1, who transmits it in turn, at a time t 1 , to cache memory L2. 
         [0044]    At a time t 2 , in response to the atomic instruction, the cache memory L2 executes a cached load command LD at address a1, which command is associated with a lock command LCK, not for a memory area, but for the local cache line L(a1) allocated to the address a1. 
         [0045]    The cache lines may be subject to concurrent access requests by the cores that share the cache memory. In practice, as shown in  FIG. 1  for cache memories L2, the cache controller may include processing units PU assigned respectively to the cores, which processing units compete for gaining access to the cache lines. From time t 2 , access to the cache line L(a1) is reserved exclusively to the core CPUa that executed the atomic instruction. The lock interval is indicated by a bold line. 
         [0046]    The effect of the load command LD may be similar to the response of the cache memory to a load instruction of same name executed by the core. This command then causes, through usual cache management mechanisms, a validity checking of the cache line allocated to the address a1, in other words if the cache line is present and has not been invalidated by the coherence management mechanism. If the cache line is invalid or absent (cache-miss), the cache controller requests a refill from the downstream memory, where the downstream memory may be the system memory MEM, or a higher-level cache memory (L3), if the processor has one. 
         [0047]    At a time t 3 , if a refill was requested, the new content of the cache line is received from the downstream memory, including the up-to-date value val of the shared variable at address a1. 
         [0048]    Upon refilling a cache line, the interval t 2 -t 3  corresponds to the latency of the downstream memory. However, the likelihood that the cache line is valid is non-negligible, whereby the cache line refill is omitted and interval t 2 -t 3  is zero, since the cache controller can then immediately chain the subsequent operations. 
         [0049]    At a time t 4 , the cache memory L2 transmits the read value val to the cache memory L1 and may then locally add the increment i to the value val. 
         [0050]    At a time t 5 , the cache memory L1 acknowledges the operation to the core CPUa, for instance by transmitting the read value val to the core CPUa. The cache memory L2 executes a command ST for storing the modified value at the address a1. The effect of the store command ST may be similar to the response of the cache memory to a store instruction of same name executed by the core. This command may then cause, by usual cache management mechanisms, updating of the cache line allocated to address a1, and marking the cache line as “dirty”. The cache line may then, for example, be transferred to a write-buffer, and be invalidated in the other L2 cache memories by the coherence management mechanism. 
         [0051]    According to an alternative, invalidation of the cache line in the other cache memories of same level may be omitted, since the shared variable is shared only among the cores connected to the same cache memory. In other words, the other cores may continue accessing data without latency in their cache line, and will not, in principle, access the obsolete shared variable in this cache line. 
         [0052]    At a time t 7 , as soon as the shared variable is up-to-date in the cache line, the cache line may be unlocked (ULCK) and an acknowledgement may be sent to cache memory L1. From this time, the cache memory L2 may flush its write-buffer to the system memory MEM, or to a higher-level cache memory L3 that relays the flushing to the system memory. 
         [0053]    It shall be noted that the lock interval of the cache line is shorter than the lock interval of the system memory in  FIG. 2 , especially when the shared variable is up-to-date in the cache line, avoiding a read operation in the downstream memory between times t 2  and t 3 . 
         [0054]    A significant gain is achieved due to the fact that only the cache line allocated to the address of the shared variable is locked, instead of the system memory. Access to other cache lines at to all the system memory remains authorized to competing cores during local atomic operations. 
         [0055]    As previously indicated, in some processor architectures, conventional atomic instructions may be implemented through a second technique, based on a cache coherence protocol by which the cache line containing the shared variable targeted by the atomic instruction is acquired in “exclusive” mode by the core executing the atomic instruction. In such an architecture, an atomic instruction having a local scope limited to a given cache level (for instance L2) improves performance by avoiding the exclusive locking mode, which otherwise requires the exchange of messages between the controllers of same-level cache memories. Moreover, since the cache line is not locked in exclusive mode, the cores connected to another cache memory of same level can still access their cache line as usual. 
         [0056]    In the preceding description, it was assumed that the scopes of the atomic instructions (local or global) were differentiated by dedicated atomic instruction families of the processor instruction set, i.e. having distinct opcodes. According to another embodiment, a same family of atomic instructions may be used, that may be qualified as generic, and the scopes are then differentiated by using functionality conventionally offered by a memory management unit MMU. Indeed, an MMU may be configured to assign various memory transaction modes to virtual address spaces, and offers flexibility for translating virtual address spaces to physical address spaces. The memory transaction modes are generally programmable by the operating system in the MMU by setting “attributes” assigned to the virtual address spaces. 
         [0057]    It is proposed, in this context, to configure the MMU for translating two distinct virtual address spaces to a same physical address space containing the shared variable, and to differentiate the scope of the atomic instruction by setting the memory transaction mode. The first virtual address space is assigned to the local scope, and a “cached” attribute is used for this purpose. The “cached” mode usually being the default mode, this mode is established without setting a specific attribute in certain systems. The second virtual address space is assigned to the global scope, and an “uncached” attribute is used for this purpose. 
         [0058]    The values of the attributes are generally conveyed on separate lines of the address busses, so that they may be taken into account by the cache controllers, in particular. A cache controller thus receives the physical address of the shared variable—translated by the MMU from whichever virtual address space was used by the instruction—and an attribute indicating the scope of the instruction, whose value depends on the virtual address space used by the instruction. 
         [0059]    With this configuration, the cache controller may implement a same generic atomic instruction with a local or global scope depending on whether the address passed as a parameter to the instruction for accessing the shared variable is in the first or second virtual address space.