Patent Description:
In parallel programming computing environments, when parallel processor cores or programs share access to the same memory locations, this access must be properly managed and synchronized. In some such environments, a transactional memory paradigm may be employed to manage synchronized memory access by threads. According to a transactional memory approach, threads can speculatively execute transactions without altering the contents of shared memory locations until the transactions subsequently commit. If a conflict is detected between two transactions, one of the transactions may be aborted so that the other transaction can commit, at which time the committed transaction may alter the contents of the shared memory locations.

More specifically, a conventional multiprocessor computer system includes multiple processing units as well as one or more address, data and control buses. Coupled to the multiple processing units is a system memory, which represents the lowest level of volatile memory in the multiprocessor computer system and which generally is accessible for read and write access by all processing units. In order to reduce access latency to instructions and data residing in the system memory, each processing unit is typically further supported by a respective multi-level cache hierarchy, the lower level(s) of which may be shared by one or more processor cores.

Cache memories are commonly utilized to temporarily buffer memory blocks that might be accessed by a processor in order to speed up processing by reducing access latency introduced by having to load needed data and instructions from system memory. In some multiprocessor systems, the cache hierarchy includes at least two levels. The level one (L1) or upper-level cache is usually a private cache associated with a particular processor core and cannot be accessed by other cores in a multiprocessor system. Typically, in response to a memory access instruction such as a load or store instruction, the processor core first accesses the directory of the upper-level cache. If the requested memory block is not found in the upper-level cache, the processor core then accesses lower-level caches (e.g., level two (L2) or level three (L3) caches) or system memory for the requested memory block. The lowest level cache (e.g., L3 cache) is often shared among several processor cores.

In such systems, multiprocessor software concurrently accesses shared data structures from multiple software threads. When concurrently accessing shared data it is typically necessary to prevent so-called "unconstrained races" or "conflicts". A conflict occurs between two memory accesses when they are to the same memory location and at least one of them is a write and there is no means to ensure the ordering in which those accesses occur.

Multiprocessor software typically utilizes lock variables to coordinate the concurrent reading and modifying of locations in memory in an orderly conflict-free fashion. A lock variable is a location in memory that is read and then set to a certain value, possibly based on the value read, in an atomic fashion. The read-modify-write operation on a lock variable is often accomplished utilizing an atomic-read-modify-write instruction or by a sequence of instructions that provide the same effect as a single instruction that atomically reads and modifies the lock variable.

In this manner, a software thread reading an initial "unlocked" value via an atomic-read-modify-write instruction is said to have "acquired" the lock and will, until it releases the lock, be the only software thread that holds the lock. The thread holding the lock may safely update the shared memory locations protected by the lock without conflict with other threads because the other threads cannot obtain the lock until the current thread releases the lock. When the shared locations have been read and/or modified appropriately, the thread holding the lock releases the lock (e.g., by writing the lock variable to the "unlocked" value) to allow other threads to access the shared locations in storage.

While locking coordinates the accesses of competing threads to shared data, locking suffers from a number of well-known shortcomings. These include, among others, firstly the possibility of deadlock when a given thread holds more than one lock and prevents the forward progress of other threads and secondly the performance cost of lock acquisition forward progress of other threads and secondly the performance cost of lock acquisition when the lock may not have been strictly necessary because no conflicting accesses would have occurred to the shared data.

To overcome these limitations, the notion of transactional memory can be employed. In transactional memory, a set of load and/or store instructions are treated as a "transaction. " A transaction succeeds when the constituent load and store operations can occur atomically without a conflict with another thread. The transaction fails in the presence of a conflict with another thread and can then be re-attempted. If a transaction continues to fail, software may fall back to using locking to ensure the orderly access of shared data.

To support transactional memory, the underlying hardware tracks the storage locations involved in the transaction, i.e. the transaction footprint, as the transaction executes for conflicts. If a conflict occurs in the transaction footprint, the transaction is aborted and possibly restarted. Use of transactional memory reduces the possibility of deadlock due to a thread holding multiple locks because, in the typical case, no locks are held (the transaction simply attempts to make one or more storage accesses and restarts if a conflict occurs). Further, the processing overhead of acquiring a lock is generally avoided.

Transaction memory is known in the form of hardware transactional memory (HTM) and software transactional memory (STM). Hardware transactional memory (HTM) systems may comprise modifications in processors, cache and bus protocol to support transactions. Software transactional memory (STM) provides transactional memory semantics in a software runtime library or the programming language. Some future multicore processor generations will implement a form of hardware transactional memory (HTM), as can be taken from the document "Intel® Architecture Instruction Set Extensions Programming Reference".

The disclosure "<NPL>, discloses a software-based mechanism to blur the volatility-persistence boundary so as to reduce the overhead in transaction support.

The disclosure "<NPL>, discloses a persistent transactional memory, a new design that adds durability to transactional memory by incorporating with the emerging non-volatile memory.

The disclosure "<NPL> discloses a mechanism, called loose ordering consistency, that satisfies the ordering requirements of persistent memory writes at significantly lower performance degradation than other mechanisms.

The disclosure "<NPL>, discloses an interface for programming with persistent memory thereby addressing the challenges on how to create and manage such memory and how to assure consistency in the presence of failures.

It is an object of the invention to provide an improved data processing system and method.

The disclosure " <NPL> discloses a mechanism, called loose ordering consistency, that satisfies the ordering requirements of persistent memory writes at significantly lower performance degradation than other mechanisms.

It is an object of the invention to provide an improved data processing system and method. the indicator is set, and set the HTM transaction to unlogged state, in particular unset the indicator, if the redo of the transaction is completed.

According to a fifth implementation of the first aspect, the data processing system is further configured to flush the data written by the HTM operation from the cache memory to the nonvolatile memory after the successful commit of the HTM transaction.

According to the sixth implementation form of the first aspect, the data processing system is further configured to set the HTM transaction to unlogged state, in particular unset the indicator after the successful commit of the HTM transaction.

According to a seventh implementation of the first aspect, the data processing system is further configured to transparently flush the data written by the HTM operation from the cache memory to the nonvolatile memory without aborting a HTM transaction.

According to an eighths implementation form of the first aspect, the indicator indicating the successful commit of the HTM transaction comprises a HTM transaction identifier, in particular a commit record.

According to a second aspect, a data processing method for performing a hardware transactional memory (HTM) transaction comprises the step of executing an atomic HTM write operation in connection with committing the HTM transaction by writing an indicator to a nonvolatile memory indicating a successful commit of the HTM transaction.

A first implementation form of the second aspect comprises the step of executing a write operation associated with the HTM transaction in the nonvolatile memory by transparently flushing the log of the write operation associated with the HTM transaction to the nonvolatile memory prior to the successful commit of the HTM transaction.

A second implementation form of the second aspect comprises the step of redoing the log upon a restart of the data processing system, if the log of the write operation associated with the HTM transaction is present in the nonvolatile memory and the HTM transaction is in logged state, in particular setting the indicator, and setting the HTM transaction to unlogged state, in particular unsetting the indicator, if the redoing of the transaction is completed.

A third implementation form of the second aspect comprises the step of flushing the data written by the HTM operation from the cache memory to the nonvolatile memory after the successful commit of the HTM transaction.

A fourth implementation form of the second aspect comprises the step of setting the HTM transaction to unlogged state, in particular unsetting the indicator after the successful commit of the HTM transaction.

A fifth implementation form of the second aspect comprises the step of transparently flushing the data written by the HTM operation from the cache memory to the nonvolatile memory without aborting a HTM transaction.

According to a third aspect of the invention, a computer program code for performs the data processing method of the second aspect or its implementation forms when executed on a computer.

Further embodiments of the invention will be described with respect to the following figures, in which:.

In the following detailed description, reference is made to the accompanying drawings, which form a part of the disclosure, and in which are shown, by way of illustration, specific aspects in which the disclosure may be practiced.

It is understood that a disclosure in connection with a described method may also hold true for a corresponding device or system configured to perform the method and vice versa. For example, if a specific method step is described, a corresponding device or system may include a unit to perform the described method step, even if such unit is not explicitly described or illustrated in the figures.

<FIG> shows a schematic diagram of a data processing system <NUM> according to an embodiment. The data processing system <NUM> is configured to perform a hardware transactional memory (HTM) transaction. The data processing system <NUM> comprises a byte-addressable nonvolatile memory <NUM> for persistently storing data and a processor <NUM>. The processor <NUM> is configured to execute an atomic HTM write operation in connection with committing the HTM transaction by writing an indicator to the nonvolatile memory indicating the successful commit of the HTM transaction. In an embodiment, the indicator can be a non-volatile bit in the commit of the HTM transaction.

Nonvolatile memory (NVM or NVRAM) is a byte-addressable memory which is durable, i.e. the data in the memory is persistent across power failures. According to the embodiment, the log records (including successful commit indicator) and application data are maintained in NVM.

According to an embodiment the HTM transaction needs to write log records and flush both log records and application data in the NVM without aborting itself or other live transactions. This requires a special type of flush instructions which are transparent to the HTM system, which we name transparent flushes (TF). Current architectures of major vendors employ flush instructions that do not evict the flushed address from the cache, which can potentially implement TF mechanism. For an example, a thread running an HTM transaction with the TSX block in X86 microarchitecture, writes a log record to the cache and then uses a CLWB instruction to flush the log record to the Log Records area in the NVM.

A recovery process reads the commit indicator from NVM after the machine restarts and if the commit indicator is set to true, which means the transaction was successful but is still logged, it reads the log records and writes to the Application Data area accordingly.

According to an embodiment the indicator can be implemented by the commit record from <FIG>. A successful commit is the point where the transaction writes are made visible atomically to all processing units in the system.

In an embodiment, the processor <NUM> is coupled to a cache memory <NUM> by a plurality of cache lines <NUM> and the cache memory <NUM> is configured to be used by the processor <NUM> for caching data using a cache coherence protocol.

In an embodiment, the data processing system <NUM> is further configured to create a log record in the Log Records area of the nonvolatile memory <NUM>, and log the write operation of cached data associated with the HTM transaction into the Log Records area. The data structure of Log Records could be referred to <FIG>, which, for example, includes Commit Record, Self_id, Size and <DATA, ADDR> tuples. Commit Record is the persistent successful commit indicator. Self id is the unique identifier of the transaction. <DATA, ADDR> tuple: A log record of the data and address of a single cache line as written by the transaction. Size is the number of log records in one transaction.

In an embodiment, the data processing system <NUM> is configured to log the write operation of cached data associated with the HTM transaction into the Log Records area by transparently flushing the log of the write operation of cached data associated with the HTM transaction to the nonvolatile memory <NUM> prior to the commit of the HTM transaction. A transparent flush is invisible to the cache memory <NUM> and to the HTM system.

In an embodiment, the data processing system <NUM> further comprises a recovery unit <NUM> configured to redo the log upon a restart of the data processing system <NUM>, if the Commit Record is set to true and the log record data , associated with the HTM operation is present in the nonvolatile memory <NUM>. Redo the log means rewriting application data area from Log Records area that is still in logged state and may not have been flushed to the nonvolatile memory <NUM> before a system failure, for instance, a power failure.

In an embodiment, the data processing system <NUM> is further configured to flush the modified application data associated with the HTM operation from the cache to the Application Data area in nonvolatile memory <NUM> after the commit of the HTM transaction.

In an embodiment, the data processing system <NUM> is further configured to transparently flush the modified application data associated with the HTM operation from the cache to the Log Records area in nonvolatile memory as in <FIG> <NUM> before the commit of the HTM transaction and to the Application Data area in nonvolatile memory as in <FIG> <NUM> after the commit of the HTM transaction without aborting a HTM transaction.

In an embodiment, the indicator indicating the successful commit of the HTM transaction comprises a HTM transaction commit record. The commit record can be a Boolean variable where a value true means the transaction is successfully committed. As long as the commit record is set, the writes of the transaction are in logged state and will be recovered in a restart.

<FIG> is a flow chart of the main stages of a persistent HTM transaction according to an embodiment.

It shows all the stages of a successful persistent HTM transaction:.

In the following, further embodiments and implementation forms of the data processing system <NUM> and the data processing method <NUM> are described in more detail using the following notation and definitions.

A HTM transaction executed, for instance, by the processor <NUM>, is denoted as Tk. A restart of the data processing system <NUM> brings the data to a consistent state, removing effects of uncommitted transactions and applying the missing effects of the committed ones (Restart). A transaction is finalized (Finalization) if it is committed successfully, and all its writes in cache are flushed to the Application Data area in the NVM <NUM> and the commit record is set to false and therefore the transaction is ignored if a subsequent restart happens. If α is a memory address in the cache <NUM>, TF(α), referred to as a Transparent Flush, will write α to the nonvolatile memory, either in the Application Data area or the Log Records area, but will not invalidate it and will not affect the cache coherency in any way.

In an embodiment, the state of a data item x (an addressable word) in the NVM <NUM>, which is written by an HTM transaction T, is defined by the following three characteristics shown in <FIG>. (<NUM>) "Private"/"Shared": "Private" means x is only in the L1 cache of one thread, and is not visible to other threads. When x is "Shared", the cache coherence makes its new value visible. (<NUM>) "Persistent"/"Volatile": "Persistent" means that the last write of x is in the NVM <NUM>; otherwise the new value of x is "Volatile" in the cache <NUM> and will disappear on a power failure. (<NUM>) "Logged"/"Clear": When x is "Logged", a restart will recover x from the non-volatile log. If x is "Clear", the restart will not touch x, because its log record has been finalized or its transaction has not been successfully committed.

<FIG> shows the state machine of a single write in a HTM transaction that can be executed by a data processing system according to the present application, for instance the data processing system <NUM> shown in <FIG>. According to an embodiment the mechanism makes the transition <"Private", "Clear"> to <"Shared", "Logged"> atomic, and allows the transition <"Volatile"> to <"Persistent"> to not abort a concurrent HTM transaction that reads the item. Generally, the "Logged" characteristic is for the entire HTM transaction. Turning all writes of a single transaction from "Clear" to "Logged" requires a single persistent write. In a HTM commit according to an embodiment of the present application, all writes are exposed by the HTM and are simultaneously logged. In an embodiment, each write generates a persistent log record, but until a successful commit, the write is not logged in the sense that it will not be replayed by a restart process. <FIG> is a detailed flow chart of the actions in the different stages.

When the HTM transaction Tk writes to a variable x, x is marked as transactional in the L1 cache, for instance, the cache <NUM> shown in <FIG>, of the processor <NUM> and is "private", i.e. exclusively in the L1 cache <NUM> of the processor <NUM>. It is "volatile", as it is only in the cache <NUM>, and "clear", i.e. not "logged", as the transaction is not yet committed. Not logged implies that x will not be written by the restart process. Upon an abort or a power failure of the data processing system <NUM>, the "volatile" and "private" value of x will be discarded and it will revert to its previous "shared" and "persistent" value.

In an embodiment, in the HTM commit the state of x changes twice. It becomes "shared", i.e. visible, and at the same time it is also "logged". In an embodiment, both changes happen atomically at a successful commit. After a successful commit, the HTM flushes the new value of x transparently to the NVM <NUM> and clears x. Clearing is first setting the commit record (indicator) to false, and in a second step unsetting the log mark. The log mark role is to verify an address is logged only by one transaction in the system and the restart process writes an address at most once by the last value that was written to the address by an HTM transaction. The log marks are an embodiment and not part of the claims in this patent. If there is a failure of the system <NUM> and restart thereof when x is "logged", the processor <NUM> is configured to write the committed value of x in the log record of x to the Application Data area in the NVM and then to clear x.

In an embodiment, the log record in the NVM <NUM> is not a typical sequential log. Instead, it can hold log records only for transactions that are either in-flight, or are committed by the HTM and their log records have not been recycled yet.

As the person skilled in the art will appreciate, if the L1 cache <NUM> was non-volatile, HTM would be persistent as is without any further modifications. A restart event could abort the in-flight transactions, and a committed HTM transaction, while in the cache <NUM>, would be instantly persistent and not require any logging. However, due to hardware limitations, e.g. fast wear out and slow writes of the NVM <NUM>, the cache hierarchy will stay in volatile SRAM for the foreseeable future.

As shown in <FIG>, in an embodiment the successful commit of the transaction Tk automatically sets the indicator, i.e. commit record of Tk to true, as shown in <FIG>. In an embodiment, this can be implemented by the processor <NUM> using a "tx_end_log(Tk)" instruction. This instruction performs an HTM commit and sets the commit record of Tk. <FIG> shows schematically the layout of the persistent footprint of the transaction Tk in the NVM <NUM> according to an embodiment. It includes the "logged" indicated which can serve as the commit record of Tk. The instruction "tx_end_log(Tk)" writes the commit record in the NVM <NUM> and in addition sets the status of the writes of Tk to "logged".

In an embodiment, the processor <NUM> is configured to flush modified data from the cache <NUM> to the NVM <NUM> by live transactions without aborting those transactions. During finalization of the transaction T, for instance, after the instruction "tx_end_log(T)", i.e. after HTM commit, flushing of the application data, written by T from the cache <NUM> to the Application Data area in NVM <NUM> does not abort ongoing concurrent transactions that read this value. In an embodiment, these flushes do not generate any coherency request and do not invalidate the data in the case <NUM>. Such operations are herein referred to as transparent flushes (TF) as they have no effect on the cache hierarchy and the HTM subsystem.

In an embodiment, the processor <NUM> can provide an API for a HTM transaction including a "tx_start()" and a "tx_end()" function which start and commit an HTM transaction. Non-persistent HTM realizations include such functions. In persistent HTM "tx_start()" is starting an HTM transaction, as in the volatile case, while "tx_end()" is extended to flushing the transaction log records from the cache to the Log Records area in NVM, followed by a simultaneous HTM commit and indicator setting, called from an API such as "tx_end_log(T)" instruction, followed by flushing of the application data itself from cache to the Application Data area in NVM. In an embodiment, the machine store instructions can be replaced by a preprocessor with a function such as "tx_write(address, data, size)" function. The tx_write() function creates a log record in the Log Records area in NVM, e.g. by non-temporal writes, and writes the application data to cache of the application data. In an embodiment, the log records and the size field that appear in the HTM transaction shown in <FIG> are flushed as part of the transaction, but not as part of the commit instruction. However, multiple writes to the same cache line can write to the same log record. Thus, in an embodiment, the log records are flushed only once before commit to prevent multiple flushes of the same data.

In an embodiment, the processor <NUM> is configured to follow a best effort policy in the sense that the processor <NUM> does not supply a progress guarantee. As a result, after a certain number of aborts in the conventional volatile HTM, the transaction must take a global lock and commit. However with a NVM, a global lock is not enough as the tentative writes may have already contaminated memory. Therefore, in an embodiment an undo log entry is created for every volatile HTM write. In an alternative embodiment, a full redo log is created before the first value is written to the NVM <NUM>. The first embodiment reduces read after write overhead.

As already described above, with a volatile cache, such as the cache <NUM> shown in <FIG>, and committed HTM transactions that accommodate all their writes in cache, in an embodiment the processor <NUM> is configured to log the writes in order to allow recovery in case a restart happened after HTM commit, when the writes were still volatile. In an embodiment, the processor <NUM> is configured such that all writes to the log reach the NVM <NUM> before an HTM commit, while all transactional writes stay in the cache <NUM>. In an embodiment, the processor <NUM> is configured to flush the log to the NVM <NUM> without aborting the executing transaction, i.e. transparently, as already described above.

In an embodiment, the processor <NUM> is configured such that logging can provide a restart process with the last committed value for each logged variable x. In an embodiment, the processor <NUM> is configured to attach a version to x. In an embodiment, the processor <NUM> is configured to verify that x is logged only once in the system <NUM>. If the appearance of x in multiple logs is allowed, then the latest version of the log of x should be kept.

In an embodiment, each address is allowed to appear at most in one log. To avoid instances of the same address in multiple logs, in an embodiment a volatile array of log marks, is added in which each memory address is mapped to one mark. In an embodiment, when a transaction is about to write x, it also marks x as logged. In an embodiment, until x is flushed, no other transaction is allowed to write it. The reason marks or indicators are used in an embodiment is to prevent a write to a variable that was already written to another transaction, but not yet flushed, so it is still logged. All other conflicts can be handled directly by the HTM. In an embodiment, the array of marks or indicators can be volatile, as in case of a restart it is known that the logged addresses are unique, and that the restart and recovery process do not create any new log records. After restart, a new and empty array of marks or indicators can be allocated according to an embodiment.

In an embodiment, the writing of the marks or indicators is a part of a transaction, i.e. if the transaction Tk writes x, it also marks x and in committing, the writing and the marking will take effect simultaneously as they are both transactional writes, while at abort, they are both canceled. In an embodiment, as long as the mark is set, the value of x, which appears in the log of Tk, cannot be changed. Therefore, after x is flushed from the cache to the Application Data area in the NVM <NUM> and the commit record is set to false, the mark can be unset. It is important to emphasize that the transactional load instructions can ignore the marks and execute in full speed, which is a key advantage of HTM according to the present application as read transactions are processed in hardware speed.

<FIG> shows the persistent structure of the log records of a transaction T according to an embodiment. In an embodiment, T has a Boolean commit record as shown in <FIG>, which is set in tx_end_log. In an embodiment, the commit record is written by the HTM commit microcode, thus it should reside on the fastest available nonvolatile memory. In an embodiment, the transaction also has a unique ID which is stored in self_id. In an embodiment, the transaction has a set of log records. In an embodiment, each log record, as shown in <FIG>, consists from the data in a modified cache line and the address of that line in system memory. In an embodiment, the maximal total size of the data is equal to the size of the L1 cache <NUM>, which is the maximal size of written and, thus, logged, data. In an embodiment, the size field is the number of log records in the log of the transaction. In an embodiment, logged and size can be united, assuming if size is zero the transaction is not logged. However, for the sake of clarity here they are treated separately. In an embodiment, all of the Log Records area from <FIG>, of T is flushed to the NVM <NUM> only once, so if a cache line is written multiple times in the same transaction, the data of this line is flushed to the log only once before the commit of T.

In an embodiment, the DATA. ADDR field in the log record, which is the address and corresponding data of the application data in NVM, allows a restart process or a finalization to know which address and application data to write or flush. In an embodiment, the address is in a separate array, and not appended to the data, to avoid fragmentation of the cache. In an embodiment, a mapping of the address itself is used to occupy and free the mark in write instrumentation and finalization. fragmentation of the cache. In an embodiment, a mapping of the address itself is used to occupy and free the mark in write instrumentation and finalization.

Claim 1:
A data processing system (<NUM>) for performing a hardware transactional memory (HTM) transaction associated to a thread, the data processing system (<NUM>) comprising:
a byte-addressable nonvolatile memory (<NUM>) for persistently storing data, the nonvolatile memory (<NUM>) comprising a log records area and an application data area;
a multithreaded processor (<NUM>); and
a private cache memory (<NUM>) to the processor (<NUM>);
the processor (<NUM>) being configured to:
- execute an atomic HTM write operation;
- commit the HTM transaction by writing a commit record to the log records area of the nonvolatile memory (<NUM>) indicating a successful commit of the HTM transaction thereby setting the HTM transaction in a logged state;
- log a write operation associated with the HTM transaction in the log records area of the nonvolatile memory (<NUM>) prior to the successful commit of the HTM transaction;
- flush the data written by the HTM write operation from the private cache memory (<NUM>) to the application data area of the nonvolatile memory (<NUM>) after the successful commit of the HTM transaction; and
characterized in that the processor is further configured to:
- set the HTM transaction to an unlogged state by unsetting the commit record, after the successful flushing of the data; and
wherein the data processing system (<NUM>) further comprises a recovery unit (<NUM>) configured to:
- redo the log upon a restart of the data processing system (<NUM>), if the log of the write operation associated with the HTM transaction is present in the nonvolatile memory (<NUM>) and if the commit record is set, and
- set the HTM transaction to an unlogged state by unsetting the commit record, if the redo of the transaction is completed.