# Intel® Transactional Synchronization Extensions (Intel® TSX) Programming Considerations

Typical programmer-identified regions are expected to transactionally execute and commit successfully. However, Intel® Transactional Synchronization Extensions (Intel® TSX) does not provide any such guarantee. A transactional execution may abort for many reasons. To take full advantage of the transactional capabilities, programmers should take into account programming considerations to increase the probability of their transactional execution committing successfully.

This section discusses various events that may cause transactional aborts. The architecture ensures that updates performed within a transaction that subsequently aborts execution will not become visible: Only a committed transactional execution updates architectural state. Transactional aborts never cause functional failures and only affect performance.

## Instruction Based Considerations

Programmers can use any instruction safely inside a transaction, Hardware Lock Elision (HLE) or Restricted Transactional Memory (RTM) and can use transactions at any privilege level. Some instructions will always abort the transactional execution and cause execution to seamlessly and safely transition to a non-transactional path.

Intel® TSX allows for most common instructions to be used inside transactions without causing aborts. The following operations inside a transaction do not typically cause an abort:

- Operations on the instruction pointer register.
- Operations on general purpose registers (`GPR`s).
- Operations on the status flags (CF, OF, SF, PF, AF, and ZF).
- Operations on `XMM` and `YMM` registers.
- Operations on the `MXCSR` register.

### Note

Programmers must be careful when intermixing Intel® Supplemental Streaming Extensions (Intel® SSE) and Intel® Advanced Vector Extensions (Intel® AVX) operations inside a transactional region. Intermixing Intel® SSE instructions accessing `XMM` registers and Intel® AVX instructions accessing `YMM` registers may cause transactions to abort.

Programmers may use `REP`/`REPNE` prefixed string operations inside transactions. However, long strings may cause aborts. Further, the use of `CLD` and `STD` instructions may cause aborts if they change the value of the DF flag. If DF is '1', the `STD` instruction will not cause an abort. Similarly, if DF is '0', the `CLD` instruction will not cause an abort.

Instructions not enumerated here as causing abort when used inside a transaction will typically not cause a transaction to abort (examples include but are not limited to `MFENCE`, `LFENCE`, `SFENCE`, `RDTSC`, `RDTSCP`, etc.).

The following instructions will abort transactional execution on any implementation:

- `XABORT`
- `CPUID`
- `PAUSE`

In some implementations, the following instructions may always cause transactional aborts. These instructions are not expected to be commonly used inside typical transactional regions. Programmers must not rely on these instructions to force a transactional abort, since whether they cause transactional aborts is implementation dependent.

- Operations on X87 and MMX™ architecture state. This includes all MMX™ and X87 instructions, including the `FXRSTOR` and `FXSAVE` instructions.
- Update to non-status portion of EFLAGS:`CLI`, `STI`, `POPFD`, `POPFQ`, `CLTS`.
- Instructions that update segment registers, debug registers and/or control registers:`MOV` to `DS`/`ES`/`FS`/`GS`/`SS`, `POP` `DS`/`ES`/`FS`/`GS`/`SS`, `LDS`, `LES`, `LFS`, `LGS`, `LSS`, `SWAPGS`, `WRFSBASE`, `WRGSBASE`, `LGDT`, `SGDT`, `LIDT`, `SIDT`, `LLDT`, `SLDT`, `LTR`, `STR`, `Far CALL`, `Far JMP`, `Far RET`, `IRET`, `MOV` to DRx, `MOV` to `CR0`/`CR2`/`CR3`/`CR4`/`CR8`, and `LMSW`.
- Ring transitions:`SYSENTER`, `SYSCALL`, `SYSEXIT`, and `SYSRET`.
- TLB and Cacheability control:`CLFLUSH`, `INVD`, `WBINVD`, `INVLPG`, `INVPCID`, and memory instructions with a non-temporal hint (`MOVNTDQA`, `MOVNTDQ`, `MOVNTI`, `MOVNTPD`, `MOVNTPS`, and `MOVNTQ`).
- Processor state save:`XSAVE`, `XSAVEOPT`, and `XRSTOR`.
- Interrupts:`INTn`, `INTO`.
- IO:`IN`, `INS`, `REP INS`, `OUT`, `OUTS`, `REP OUTS` and their variants.
- VMX: `VMPTRLD`, `VMPTRST`, `VMCLEAR`, `VMREAD`, `VMWRITE`, `VMCALL`, `VMLAUNCH`, `VMRESUME`, `VMXOFF`, `VMXON`, `INVEPT`, and `INVVPID`.
- SMX:`GETSEC`, `UD2`, `RSM`, `RDMSR`, `WRMSR`, `HLT`, `MONITOR`, `MWAIT`, `XSETBV`, `VZEROUPPER`, `MASKMOVQ`, and `V/MASKMOVDQU`.

## Runtime Considerations

In addition to instruction-based considerations, runtime events may cause transactional execution to abort. These may be due to data access patterns or micro-architectural implementation causes. The following list is not a comprehensive discussion of all abort causes:

Any fault or trap in a transaction that must be exposed to software will be suppressed. Transactional execution will abort and execution will transition to a nontransactional execution as if the fault or trap had never occurred. If any exception is not masked, that will result in a transactional abort and it will be as if the exception had never occurred.

Synchronous exception events (#DE, #OF, #NP, #SS, #GP, #BR, #UD, #AC, #XF, #PF, #NM, #TS, #MF, #DB, #BP/INT3) that occur during transactional execution may cause an execution not to commit transactionally, and require a non-transactional execution. These events are suppressed as if they had never occurred. With HLE, since the non-transactional code path is identical to the transactional code path, these events will typically re-appear when the instruction that caused the exception is re-executed non-transactionally, causing the associated synchronous events to be delivered appropriately in the non-transactional execution.

Asynchronous events (NMI, SMI, INTR, IPI, PMI, etc.) occurring during transactional execution may cause the transactional execution to abort and transition to nontransactional execution. The asynchronous events will be queued and handled after the transactional abort is processed.

Transactions only support write-back cacheable memory type operations. A transaction may always abort if it includes operations on any other memory type. This includes instruction fetches to `UC` memory type.

Memory accesses within a transactional region may require the processor to set the Accessed and Dirty flags of the referenced page table entry. The behavior of how the processor handles this is implementation specific. Some implementations may allow the updates to these flags to become externally visible even if the transactional region subsequently aborts. Some Intel® TSX implementations may choose to abort the transactional execution if these flags need to be updated. Further, a processor's page-table walk may generate accesses to its own transactionally written but uncommitted state. Some Intel® TSX implementations may choose to abort the execution of a transactional region in such situations. The architecture ensures that if the transactional region aborts, the transactionally written state will not be made architecturally visible through the behavior of structures such as TLBs.

Executing self-modifying code transactionally may also cause transactional aborts. Programmers must continue to follow Intel recommended guidelines for writing self-modifying and cross-modifying code even when employing HLE and RTM.

While an implementation of RTM and HLE will typically provide sufficient resources for executing common transactional regions, implementation constraints and excessive sizes for transactional regions may cause a transactional execution to abort and transition to a non-transactional execution. The architecture provides no guarantee of the amount of resources available to do transactional execution and does not guarantee that a transactional execution will ever succeed.

Conflicting requests to a cache line accessed within a transactional region may prevent the transaction from executing successfully. For example, if logical processor P0 reads line A in a transactional region and another logical processor P1 writes A (either inside or outside a transactional region) then logical processor P0 may abort if logical processor P1’s write interferes with processor P0's ability to execute transactionally.

Similarly, if P0 writes line A in a transactional region and P1 reads or writes A (either inside or outside a transactional region), then P0 may abort if P1's access to A interferes with P0's ability to execute transactionally. Other coherence traffic may at times appear as conflicting requests and may cause aborts. While these false conflicts may happen, they are expected to be uncommon. The conflict resolution policy to determine whether P0 or P1 aborts in the above scenarios implementation specific.

Parent topic: Intrinsics for Intel® Transactional Synchronization Extensions (Intel® TSX)