Java CAS principle analysis, MySQL 10 million data deep paging optimization

The CAS operation process mentioned above is not very difficult. But the above description is not enough. Next, I will introduce some other background knowledge. With these background knowledge, we can better understand the follow-up content.

2. Background introduction

As we all know, CPU transmits data through bus and memory. In the multi-core era, multiple cores communicate with memory and other hardware through the same bus. As shown below:

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-zmhqeibe-1630033228588)( https://blog.csdn.net/ )]

Picture source: in depth understanding of computer systems

The figure above is a relatively simple computer structure diagram. Although it is simple, it is enough to illustrate the problem. In the figure above, the CPU communicates with the memory through the bus marked by two blue arrows. Let's consider a problem. If multiple cores of the CPU operate on the same piece of memory at the same time, what kind of errors will be caused if they are not controlled? Here is a brief explanation. Suppose that core 1 writes 64 bit data to memory through a 32-bit bandwidth bus, and core 1 needs to write twice to complete the whole operation. If core 1 writes 32-bit data for the first time, core 2 reads 64 bit data from the memory location written by core 1. Since core 1 has not completely written all 64 bit data into memory, core 2 starts reading data from the memory location, then the read data must be chaotic.

However, there is no need to worry about this problem. Through the Intel Developer's manual, we can learn that since the Pentium processor, the Intel processor will guarantee to read and write quadword s aligned with 64 bit boundaries in an atomic manner.

According to the above description, we can conclude that Intel processors can ensure that memory aligned instructions are executed atomically in a single access. But what if it is an instruction to access memory twice? The answer is no guarantee. For example, the increment instruction inc dword ptr [...], Equivalent to DEST = DEST + 1. The instruction contains three operations read - > change - > write, involving two memory accesses. Consider the case where a value of 1 is stored at the specified location in memory. Now the two CPU cores execute the instruction at the same time. The process of alternate execution of the two cores is as follows:

  1. Core 1 reads the value 1 from the specified location in memory and loads it into the register

  2. Core 2 reads the value 1 from the specified location in memory and loads it into the register

  3. Core 1 decrements the value of the register by 1

  4. Core 2 decrements the value of the register by 1

  5. Core 1 writes the modified value back to memory

  6. Core 2 writes the modified value back to memory

After executing the above process, the final value in memory is 2, and we expect 3, which is a problem. To deal with this problem, it is necessary to avoid two or more cores operating the same memory area at the same time. So how to avoid it? This requires the introduction of the protagonist lock prefix. For a detailed description of the instruction, please refer to the Intel Developer's Manual Volume 2 Instruction Set Reference, Chapter 3 Instruction Set Reference A-L. I quote a paragraph here as follows:

LOCK—Assert LOCK# Signal Prefix

Causes the processor's LOCK# signal to be asserted during execution of the accompanying instruction (turns the instruction into an atomic instruction). In a multiprocessor environment, the LOCK# signal ensures that the processor has exclusive use of any shared memory while the signal is asserted.

The key points described above have been marked in bold. In a multiprocessor environment, the lock# signal can ensure that the processor has exclusive use of some shared memory. lock can be added before the following command:

ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG.

By adding the lock prefix before the inc instruction, the instruction can be made atomic. When multiple cores execute the same inc instruction at the same time, it will be carried out in serial mode, which avoids the situation mentioned above. Then there is another problem. How does the lock prefix ensure that the core monopolizes a certain memory area? The answer is as follows:

In Intel processors, there are two ways to ensure that a core of the processor monopolizes a memory area. The first way is to LOCK the bus and let a core use the bus exclusively, but this is too expensive. After the bus is locked, other cores cannot access memory, which may cause other cores to stop working for a short time. The second way is to LOCK the cache if somewhere in memory data is cached in the processor cache. The LOCK # signal issued by the processor does not LOCK the bus, but locks the memory area corresponding to the cache line. Other processors cannot operate on this memory area while it is locked. Compared with locking the bus, the cost of locking the cache is obviously small. For more detailed descriptions of bus locks and cache locks, please refer to Intel Developer's Manual Volume 3 Software Developer's manual, Chapter 8 multiple processor management.

3. Source code analysis

With the above background knowledge, now we can calmly read the source code of CAS. The content of this chapter will be about Java util. concurrent. The compareAndSet method in the atomic class AtomicInteger under the atomic package is analyzed. The correlation analysis is as follows:

`public class AtomicInteger extends Number implements java.io.Serializable {



    // setup to use Unsafe.compareAndSwapInt for updates

    private static final Unsafe unsafe = Unsafe.getUnsafe();

    private static final long valueOffset;



    static {

        try {

            // Calculates the offset of the variable value in the class object

            valueOffset = unsafe.objectFieldOffset

                (AtomicInteger.class.getDeclaredField("value"));

        } catch (Exception ex) { throw new Error(ex); }

    }



    private volatile int value;

    

    public final boolean compareAndSet(int expect, int update) {

        /*  * compareAndSet In fact, it is just a shell, and the main logic is encapsulated in Unsafe's * compareAndSwapInt method  */

        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

    }

    

    // ......

}



public final class Unsafe {

    // compareAndSwapInt is a method of type native. Let's continue

    public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);

    // ......

}`

`// unsafe.cpp

/*  * This doesn't look like a function, but don't worry, it's not the point. UNSAFE_ENTRY and UNSAFE_END is a macro, * which will be replaced with real code during precompiling. The following jboolean, jlong and jint types are also macros: * * JNI h  *     typedef unsigned char   jboolean;  *      typedef unsigned short  jchar;  *      typedef short           jshort;  *      typedef float           jfloat;  *      typedef double          jdouble;  *  *  jni_ md.h  *     typedef int jint;  *     # ifdef _ LP64 /* 64-bit */

 *     typedef long jlong;

 *     #else

 *     typedef long long jlong;

 *     #endif

 *     typedef signed char jbyte;

 */

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))

  UnsafeWrapper("Unsafe_CompareAndSwapInt");

  oop p = JNIHandles::resolve(obj);

  // Calculate the address of value according to the offset. The offset here is the valueOffset in AtomaicInteger

  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);

  // Call the function cmpxchg in Atomic, which is declared in Atomic In HPP

  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;

UNSAFE_END



// atomic.cpp

unsigned Atomic::cmpxchg(unsigned int exchange_value,

                         volatile unsigned int* dest, unsigned int compare_value) {

  assert(sizeof(unsigned int) == sizeof(jint), "more work to do");

  /*  * Call overloaded functions on different platforms according to the operating system type. During precompiling, the compiler will decide which platform overloaded * function to call. The related precompiling logic is as follows: * * atomic inline. hpp:   *    #include "runtime/atomic.hpp"  *  *    // Linux  *    #ifdef TARGET_ OS_ ARCH_ linux_ X86 * # include "atomic_linux_x86. Inline. HPP" * #endif * * / / omit some code * * / / windows * #ifdef target_ OS_ ARCH_ windows_ x86  *    # include "atomic_windows_x86.inline.hpp"  *    #endif  *  *    // BSD  *    #ifdef TARGET_ OS_ ARCH_ bsd_ X86 * # include "atomic_bsd_x86. Inline. HPP" * #endif * * next analyze atomic_ windows_ x86. inline. Implementation of cmpxchg function in HPP  */

  return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest,

                                       (jint)compare_value);

}`

The above analysis seems more, but the main process is not complicated. It's easy to understand if you don't worry about the details of the code. Next, I will analyze the Atomic::cmpxchg function on the Windows platform. Keep looking down.

`// atomic_windows_x86.inline.hpp

#define LOCK_IF_MP(mp) __asm cmp mp, 0 \

 __asm je L0 \

 __asm _emit 0xF0 \

 __asm L0:

              

inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {

  // alternative for InterlockedCompareExchange

  int mp = os::is_MP();

  __asm {

    mov edx, dest

    mov ecx, exchange_value

    mov eax, compare_value



### Finally, how to make yourself a technical expert step by step


To tell the truth, if a worker doesn't want to improve himself, there will be no meaning of work. After all, we are not old enough to provide for the aged.

When your technology is getting closer to Ali step by step p7 There is no doubt that your salary will rise, and you can learn more and deeper skills and make friends with more powerful cattle.

**Recommend one Java The necessary learning notes on the road of architecture are quite comprehensive!!!**

![](https://img-blog.csdnimg.cn/img_convert/d9724345c46bfa0e329b18f2cd63e8fb.png)

The adult world is not easy to two words. Before a time, tiktok saw a programmer who was working overtime for two weeks to 2 midnight. If you want to get a high salary in this industry, you have no choice but to improve your hard power.

You know what? Now some fresh students' internship salary has caught up with and surpassed the programmers who have been developing for 5 years, and the internship salary is 26 K,30K,Don't you have a sense of urgency? It's really embarrassing to be a fresh student after so many years!

If you enter this industry, don't use the lack of time to learn as an excuse. This industry is to keep learning, otherwise you can only be laid off. Therefore, seize the time to invest in yourself, learn more technology, face difficulties and relax in the future!

To get these carefully sorted out materials, please remember

630033228590)]

The adult world is not easy to two words. Before a time, tiktok saw a programmer who was working overtime for two weeks to 2 midnight. If you want to get a high salary in this industry, you have no choice but to improve your hard power.

You know what? Now some fresh students' internship salary has caught up with and surpassed the programmers who have been developing for 5 years, and the internship salary is 26 K,30K,Don't you have a sense of urgency? It's really embarrassing to be a fresh student after so many years!

If you enter this industry, don't use the lack of time to learn as an excuse. This industry is to keep learning, otherwise you can only be laid off. Therefore, seize the time to invest in yourself, learn more technology, face difficulties and relax in the future!

To get these carefully sorted out materials, please remember

**--[Attention]+[Forward]+[Support me! Creation is not easy![Click here to go to my Tencent document for free download](https://codechina.csdn.net/m0_60958482/java-p7)**

Keywords: Java Database MySQL Programmer

Added by Quevas on Sun, 19 Dec 2021 04:07:17 +0200