CUDA(C)磁态蒙特卡洛和传输矩阵多GPU并行计算分析

news2024/10/25 17:27:20

🎯要点

  1. 使用英伟达GPU、大都会和并行回火算法模拟蒙特卡洛。
  2. 使用兰佐斯算法计算传输矩阵特征值。
  3. 使用 Suzuki-Trotter 公式归一化量子无序系统。
  4. 算法模型特征:多CUDA线程,多GPU和多任务式并行计算。

🍁磁态分析角度

  • Python和MATLAB自旋玻璃投资组合神经网络广义方程
  • Python和C++及MATLAB低温磁态机器学习模型
    在这里插入图片描述

🍪语言内容分比

在这里插入图片描述
在这里插入图片描述

🍇CUDA矩阵乘法二维块平铺实现

从数学上讲,给定一个广义矩阵乘法运算 D = A B + C D=A B+C D=AB+C,其中 D ∈ R m × n , A ∈ R m × k , B ∈ R k × n , C ∈ R m × n D \in R ^{m \times n}, A \in R ^{m \times k}, B \in R ^{k \times n}, C \in R ^{m \times n} DRm×n,ARm×k,BRk×n,CRm×n,矩阵可以分成更小的矩阵。
A = [ A 1 , 1 d b m × d b k A 1 , 2 d b m × d b k … A 1 , k d m m × d b k A 2 , 1 d m m × d b k A 2 , 2 d b m × d b k ⋯ A 2 , k / d b k d b m × d b k ⋮ ⋮ ⋱ ⋮ A m / d m m , 1 d m b × d b k A m / d m m , 2 d b m × d b k ⋯ A m / d b m , k / d b k d b m × d b k ] A=\left[\begin{array}{cccc} A_{1,1}^{d_{b m} \times d_{b k}} & A_{1,2}^{d_{b m} \times d_{b k}} & \ldots & A_{1, k}^{d_{m m} \times d_{b k}} \\ A_{2,1}^{d_{m m} \times d_{b k}} & A_{2,2}^{d_{b m} \times d_{b k}} & \cdots & A_{2, k / d_{b k}}^{d_{b m} \times d_{b k}} \\ \vdots & \vdots & \ddots & \vdots \\ A_{m / d_{m m}, 1}^{d_{m b} \times d_{b k}} & A_{m / d_{m m}, 2}^{d_{b m} \times d_{b k}} & \cdots & A_{m / d_{b m}, k / d_{b k}}^{d_{b m} \times d_{b k}} \end{array}\right] A= A1,1dbm×dbkA2,1dmm×dbkAm/dmm,1dmb×dbkA1,2dbm×dbkA2,2dbm×dbkAm/dmm,2dbm×dbkA1,kdmm×dbkA2,k/dbkdbm×dbkAm/dbm,k/dbkdbm×dbk

B = [ B 1 , 1 d b k × d b n B 1 , 2 d b k × d b n … B 1 , n / d b n d b k × d b n B 2 , 1 d b k × d b n B 2 , 2 d b k × d b n … B 2 , n / d b n d b k × d b n ⋮ ⋮ ⋱ ⋮ B k / d b k , 1 d b k d b n B k / d b k , 2 d b k × d b n ⋯ B k / d b k , n / d b n d b k × d b n ] B=\left[\begin{array}{cccc} B_{1,1}^{d_{b k} \times d_{b n}} & B_{1,2}^{d_{b k} \times d_{b n}} & \ldots & B_{1, n / d_{b n}}^{d_{b k} \times d_{b n}} \\ B_{2,1}^{d_{b k} \times d_{b n}} & B_{2,2}^{d_{b k} \times d_{b n}} & \ldots & B_{2, n / d_{b n}}^{d_{b k} \times d_{b n}} \\ \vdots & \vdots & \ddots & \vdots \\ B_{k / d_{b k}, 1}^{d_{b k} d_{b n}} & B_{k / d_{b k}, 2}^{d_{b k} \times d_{b n}} & \cdots & B_{k / d_{b k}, n / d_{b n}}^{d_{b k} \times d_{b n}} \end{array}\right] B= B1,1dbk×dbnB2,1dbk×dbnBk/dbk,1dbkdbnB1,2dbk×dbnB2,2dbk×dbnBk/dbk,2dbk×dbnB1,n/dbndbk×dbnB2,n/dbndbk×dbnBk/dbk,n/dbndbk×dbn

C = [ C 1 , 1 d b m × d b n C 1 , 2 d b m × d b n … C 1 , n / d b n d b m × d b n C 2 , 1 d b m × d b n C 2 , 2 d b m × d b n … C 2 , n / d b n d b m × d m n ⋮ ⋮ ⋱ ⋮ C m / d b m , 1 d b m × d l n C m / d b m , 2 d b n × d b n ⋯ C m / d b m , n / d b n d b m × d b n ] C=\left[\begin{array}{cccc} C_{1,1}^{d_{b m} \times d_{b n}} & C_{1,2}^{d_{b m} \times d_{b n}} & \ldots & C_{1, n / d_{b n}}^{d_{b m} \times d_{b n}} \\ C_{2,1}^{d_{b m} \times d_{b n}} & C_{2,2}^{d_{b m} \times d_{b n}} & \ldots & C_{2, n / d_{b n}}^{d_{b m} \times d_{m n}} \\ \vdots & \vdots & \ddots & \vdots \\ C_{m / d_{b m}, 1}^{d_{b m} \times d_{l n}} & C_{m / d_{b m}, 2}^{d_{b n} \times d_{b n}} & \cdots & C_{m / d_{b m}, n / d_{b n}}^{d_{b m} \times d_{b n}} \end{array}\right] C= C1,1dbm×dbnC2,1dbm×dbnCm/dbm,1dbm×dlnC1,2dbm×dbnC2,2dbm×dbnCm/dbm,2dbn×dbnC1,n/dbndbm×dbnC2,n/dbndbm×dmnCm/dbm,n/dbndbm×dbn

D = [ D 1 , 1 d b m × d b n D 1 , 2 d b m × d b n … D 1 , n / d b n d b m × d b n D 2 , 1 d b m × d b n D 2 , 2 d b m × d b n … D 2 , n / d b n d b m × d m n ⋮ ⋮ ⋱ ⋮ D m / d b m , 1 d b m × d b n D m / d b m , 2 d b m × d b n ⋯ D m / d b m , n / d b n d b n × d l m ] D=\left[\begin{array}{cccc} D_{1,1}^{d_{b m} \times d_{b n}} & D_{1,2}^{d_{b m} \times d_{b n}} & \ldots & D_{1, n / d_{b n}}^{d_{b m} \times d_{b n}} \\ D_{2,1}^{d_{b m} \times d_{b n}} & D_{2,2}^{d_{b m} \times d_{b n}} & \ldots & D_{2, n / d_{b n}}^{d_{b m} \times d_{m n}} \\ \vdots & \vdots & \ddots & \vdots \\ D_{m / d_{b m}, 1}^{d_{b m} \times d_{b n}} & D_{m / d_{b m}, 2}^{d_{b m} \times d_{b n}} & \cdots & D_{m / d_{b m}, n / d_{b n}}^{d_{b n} \times d_{l_m}} \end{array}\right] D= D1,1dbm×dbnD2,1dbm×dbnDm/dbm,1dbm×dbnD1,2dbm×dbnD2,2dbm×dbnDm/dbm,2dbm×dbnD1,n/dbndbm×dbnD2,n/dbndbm×dmnDm/dbm,n/dbndbn×dlm

代码实现如下:

template <typename T, size_t BLOCK_TILE_SIZE_X, size_t BLOCK_TILE_SIZE_Y,
          size_t BLOCK_TILE_SIZE_K, size_t NUM_THREADS, size_t BLOCK_TILE_SKEW_SIZE_X = 0U, size_t BLOCK_TILE_SKEW_SIZE_K = 0U>
__device__ void load_data_to_shared_memory(T const* A, size_t lda,
                                           T const* B, size_t ldb,
                                           T A_thread_block_tile[BLOCK_TILE_SIZE_Y][BLOCK_TILE_SIZE_K + BLOCK_TILE_SKEW_SIZE_K],
                                           T B_thread_block_tile[BLOCK_TILE_SIZE_K][BLOCK_TILE_SIZE_X + BLOCK_TILE_SKEW_SIZE_X],
                                           size_t thread_block_tile_idx,
                                           size_t thread_linear_idx,
                                           size_t m, size_t n,
                                           size_t k)
{

#pragma unroll
    for (size_t load_idx{0U};
         load_idx <
         (BLOCK_TILE_SIZE_Y * BLOCK_TILE_SIZE_K + NUM_THREADS - 1U) /
             NUM_THREADS;
         ++load_idx)
    {
        size_t const A_thread_block_tile_row_idx{
            (thread_linear_idx + load_idx * NUM_THREADS) /
            BLOCK_TILE_SIZE_K};
        size_t const A_thread_block_tile_col_idx{
            (thread_linear_idx + load_idx * NUM_THREADS) %
            BLOCK_TILE_SIZE_K};
        size_t const A_row_idx{blockIdx.y * BLOCK_TILE_SIZE_Y +
                               A_thread_block_tile_row_idx};
        size_t const A_col_idx{thread_block_tile_idx * BLOCK_TILE_SIZE_K +
                               A_thread_block_tile_col_idx};

        T val{static_cast<T>(0)};
        if (A_row_idx < m && A_col_idx < k)
        {
            val = A[A_row_idx * lda + A_col_idx];
        }

        static_assert(BLOCK_TILE_SIZE_K * BLOCK_TILE_SIZE_Y % NUM_THREADS ==
                      0U);

        A_thread_block_tile[A_thread_block_tile_row_idx]
                           [A_thread_block_tile_col_idx] = val;
    }

#pragma unroll
    for (size_t load_idx{0U};
         load_idx <
         (BLOCK_TILE_SIZE_K * BLOCK_TILE_SIZE_X + NUM_THREADS - 1U) /
             NUM_THREADS;
         ++load_idx)
    {
        size_t const B_thread_block_tile_row_idx{
            (thread_linear_idx + load_idx * NUM_THREADS) /
            BLOCK_TILE_SIZE_X};
        size_t const B_thread_block_tile_col_idx{
            (thread_linear_idx + load_idx * NUM_THREADS) %
            BLOCK_TILE_SIZE_X};
        size_t const B_row_idx{thread_block_tile_idx * BLOCK_TILE_SIZE_K +
                               B_thread_block_tile_row_idx};
        size_t const B_col_idx{blockIdx.x * BLOCK_TILE_SIZE_X +
                               B_thread_block_tile_col_idx};

        T val{static_cast<T>(0)};
        if (B_row_idx < k && B_col_idx < n)
        {
            val = B[B_row_idx * ldb + B_col_idx];
        }

        static_assert(BLOCK_TILE_SIZE_X * BLOCK_TILE_SIZE_K % NUM_THREADS ==
                      0U);

        B_thread_block_tile[B_thread_block_tile_row_idx]
                           [B_thread_block_tile_col_idx] = val;
    }
}

template <typename T, size_t BLOCK_TILE_SIZE_X, size_t BLOCK_TILE_SIZE_Y,
          size_t BLOCK_TILE_SIZE_K>
__global__ void gemm_v02(size_t m, size_t n, size_t k, T alpha, T const* A,
                         size_t lda, T const* B, size_t ldb, T beta, T* C,
                         size_t ldc)
{

    constexpr size_t NUM_THREADS{BLOCK_TILE_SIZE_X * BLOCK_TILE_SIZE_Y};
    size_t const thread_linear_idx{threadIdx.y * blockDim.x + threadIdx.x};

    size_t const C_col_idx{blockIdx.x * blockDim.x + threadIdx.x};
    size_t const C_row_idx{blockIdx.y * blockDim.y + threadIdx.y};

    __shared__ T A_thread_block_tile[BLOCK_TILE_SIZE_Y][BLOCK_TILE_SIZE_K];
    __shared__ T B_thread_block_tile[BLOCK_TILE_SIZE_K][BLOCK_TILE_SIZE_X];

    size_t const num_thread_block_tiles{(k + BLOCK_TILE_SIZE_K - 1) /
                                        BLOCK_TILE_SIZE_K};

    T sum{static_cast<T>(0)};
    for (size_t thread_block_tile_idx{0U};
         thread_block_tile_idx < num_thread_block_tiles;
         ++thread_block_tile_idx)
    {
        load_data_to_shared_memory<T, BLOCK_TILE_SIZE_X, BLOCK_TILE_SIZE_Y,
                                   BLOCK_TILE_SIZE_K, NUM_THREADS>(
            A, lda, B, ldb, A_thread_block_tile, B_thread_block_tile,
            thread_block_tile_idx, thread_linear_idx, m, n, k);
        __syncthreads();

#pragma unroll
        for (size_t k_i{0U}; k_i < BLOCK_TILE_SIZE_K; ++k_i)
        {

            sum += A_thread_block_tile[threadIdx.y][k_i] *
                   B_thread_block_tile[k_i][threadIdx.x];
        }
        __syncthreads();
    }
    if (C_row_idx < m && C_col_idx < n)
    {
        C[C_row_idx * ldc + C_col_idx] =
            alpha * sum + beta * C[C_row_idx * ldc + C_col_idx];
    }
}

template <typename T>
void launch_gemm_kernel_v02(size_t m, size_t n, size_t k, T const* alpha,
                            T const* A, size_t lda, T const* B, size_t ldb,
                            T const* beta, T* C, size_t ldc,
                            cudaStream_t stream)
{

    constexpr unsigned int BLOCK_TILE_SIZE_X{32U};
    constexpr unsigned int BLOCK_TILE_SIZE_Y{32U};
    constexpr unsigned int BLOCK_TILE_SIZE_K{32U};
    constexpr unsigned int NUM_THREADS{BLOCK_TILE_SIZE_X * BLOCK_TILE_SIZE_Y};
    static_assert(BLOCK_TILE_SIZE_K * BLOCK_TILE_SIZE_Y % NUM_THREADS == 0U);
    static_assert(BLOCK_TILE_SIZE_X * BLOCK_TILE_SIZE_K % NUM_THREADS == 0U);
    dim3 const block_dim{BLOCK_TILE_SIZE_X, BLOCK_TILE_SIZE_Y, 1U};
    dim3 const grid_dim{
        (static_cast<unsigned int>(n) + block_dim.x - 1U) / block_dim.x,
        (static_cast<unsigned int>(m) + block_dim.y - 1U) / block_dim.y, 1U};
    gemm_v02<T, BLOCK_TILE_SIZE_X, BLOCK_TILE_SIZE_Y, BLOCK_TILE_SIZE_K>
        <<<grid_dim, block_dim, 0U, stream>>>(m, n, k, *alpha, A, lda, B, ldb,
                                              *beta, C, ldc);
    CHECK_LAST_CUDA_ERROR();
}

此 FP32 广义矩阵乘法实现的性能在 NVIDIA GeForce RTX 3090 GPU 上达到 2.66 TFLOPS,比之前的实现好很多。不过,它距离 GPU 的理论峰值性能还相差甚远。

使用二维块平铺和一维线程平铺实现

我们首先将矩阵 B B B 的数据从共享内存缓存到寄存器中。每个具有块线程索引 ( t m , t n ) \left(t_m, t_n\right) (tm,tn) 的线程,其中 t m ∈ [ 1 , d t m / d t m ] t_m \in\left[1, d_{t m} / d_{t m}\right] tm[1,dtm/dtm] t n ∈ [ 1 , d m m ] t_n \in\left[1, d_{m m}\right] tn[1,dmm],现在负责计算小矩阵的 d t m d_{t m} dtm 个元素,其中 d t m d_{t m} dtm 是线程块大小。
( D b m , b m d m × d m ) t m t m + d m , t n = ( ∑ b k = 1 k / d k A b m , b k d m × d ∗ B b k , b n d k × d m + C b m , b n d m × d m ) t m t m + d m , t n = ∑ b k = 1 k / d m k ( ∑ t k = 1 d m ( A b m , b k d m × d k k ) t m t m + d m , t k ( B b k , b n d m × d m ) t k , t n ) + ( C b m , b n d m × d m ) t m t m + d m , t n \begin{aligned} &\begin{aligned} & \left(D_{b_m, b_m}^{d_m \times d_m}\right)_{t_m t_m+d_m, t_n}=\left(\sum_{b_k=1}^{k / d_k} A_{b_m, b_k}^{d_m \times d *} B_{b_k, b_n}^{d_k \times d_m}+C_{b_m, b_n}^{d_m \times d_m}\right)_{t_m t_m+d_m, t_n} \end{aligned}\\ &\begin{aligned} & =\sum_{b_k=1}^{k / d_{m k}}\left(\sum_{t_k=1}^{d_m}\left(A_{b_m, b_k}^{d_m \times d_{k_k}}\right)_{t_m t_m+d_m, t_k}\left(B_{b_k, b_n}^{d_m \times d_m}\right)_{t_k, t_n}\right)+\left(C_{b_m, b_n}^{d_m \times d_m}\right)_{t_m t_m+d_m, t_n} \end{aligned} \end{aligned} (Dbm,bmdm×dm)tmtm+dm,tn= bk=1k/dkAbm,bkdm×dBbk,bndk×dm+Cbm,bndm×dm tmtm+dm,tn=bk=1k/dmk(tk=1dm(Abm,bkdm×dkk)tmtm+dm,tk(Bbk,bndm×dm)tk,tn)+(Cbm,bndm×dm)tmtm+dm,tn

template <typename T, size_t BLOCK_TILE_SIZE_X, size_t BLOCK_TILE_SIZE_Y,
          size_t BLOCK_TILE_SIZE_K, size_t THREAD_TILE_SIZE_Y>
__global__ void gemm_v03(size_t m, size_t n, size_t k, T alpha, T const* A,
                         size_t lda, T const* B, size_t ldb, T beta, T* C,
                         size_t ldc)
{

    constexpr size_t NUM_THREADS{BLOCK_TILE_SIZE_X * BLOCK_TILE_SIZE_Y /
                                 THREAD_TILE_SIZE_Y};
    size_t const thread_linear_idx{threadIdx.y * blockDim.x + threadIdx.x};

    __shared__ T A_thread_block_tile[BLOCK_TILE_SIZE_Y][BLOCK_TILE_SIZE_K];
    __shared__ T B_thread_block_tile[BLOCK_TILE_SIZE_K][BLOCK_TILE_SIZE_X];

    size_t const num_thread_block_tiles{(k + BLOCK_TILE_SIZE_K - 1) /
                                        BLOCK_TILE_SIZE_K};

    T C_thread_results[THREAD_TILE_SIZE_Y] = {static_cast<T>(0)};

    for (size_t thread_block_tile_idx{0U};
         thread_block_tile_idx < num_thread_block_tiles;
         ++thread_block_tile_idx)
    {
        load_data_to_shared_memory<T, BLOCK_TILE_SIZE_X, BLOCK_TILE_SIZE_Y,
                                   BLOCK_TILE_SIZE_K, NUM_THREADS>(
            A, lda, B, ldb, A_thread_block_tile, B_thread_block_tile,
            thread_block_tile_idx, thread_linear_idx, m, n, k);
        __syncthreads();

#pragma unroll
        for (size_t k_i{0U}; k_i < BLOCK_TILE_SIZE_K; ++k_i)
        {
            size_t const B_thread_block_tile_row_idx{k_i};

            T const B_val{
                B_thread_block_tile[B_thread_block_tile_row_idx]
                                   [thread_linear_idx % BLOCK_TILE_SIZE_X]};
#pragma unroll
            for (size_t thread_tile_row_idx{0U};
                 thread_tile_row_idx < THREAD_TILE_SIZE_Y;
                 ++thread_tile_row_idx)
            {
                size_t const A_thread_block_tile_row_idx{
                    thread_linear_idx / BLOCK_TILE_SIZE_X * THREAD_TILE_SIZE_Y +
                    thread_tile_row_idx};
                size_t const A_thread_block_tile_col_idx{k_i};
                T const A_val{A_thread_block_tile[A_thread_block_tile_row_idx]
                                                 [A_thread_block_tile_col_idx]};
                C_thread_results[thread_tile_row_idx] += A_val * B_val;
            }
        }
        __syncthreads();
    }

#pragma unroll
    for (size_t thread_tile_row_idx{0U};
         thread_tile_row_idx < THREAD_TILE_SIZE_Y; ++thread_tile_row_idx)
    {
        size_t const C_row_idx{blockIdx.y * BLOCK_TILE_SIZE_Y +
                               thread_linear_idx / BLOCK_TILE_SIZE_X *
                                   THREAD_TILE_SIZE_Y +
                               thread_tile_row_idx};
        size_t const C_col_idx{blockIdx.x * BLOCK_TILE_SIZE_X +
                               thread_linear_idx % BLOCK_TILE_SIZE_X};
        if (C_row_idx < m && C_col_idx < n)
        {
            C[C_row_idx * ldc + C_col_idx] =
                alpha * C_thread_results[thread_tile_row_idx] +
                beta * C[C_row_idx * ldc + C_col_idx];
        }
    }
}

template <typename T>
void launch_gemm_kernel_v03(size_t m, size_t n, size_t k, T const* alpha,
                            T const* A, size_t lda, T const* B, size_t ldb,
                            T const* beta, T* C, size_t ldc,
                            cudaStream_t stream)
{

    constexpr unsigned int BLOCK_TILE_SIZE_X{64U};
    constexpr unsigned int BLOCK_TILE_SIZE_Y{64U};
    constexpr unsigned int BLOCK_TILE_SIZE_K{8U};

    constexpr unsigned int THREAD_TILE_SIZE_Y{8U};
    constexpr unsigned int NUM_THREADS_PER_BLOCK{
        BLOCK_TILE_SIZE_X * BLOCK_TILE_SIZE_Y / THREAD_TILE_SIZE_Y};
    static_assert(BLOCK_TILE_SIZE_Y % THREAD_TILE_SIZE_Y == 0U);
    static_assert(NUM_THREADS_PER_BLOCK % BLOCK_TILE_SIZE_K == 0U);
    static_assert(NUM_THREADS_PER_BLOCK % BLOCK_TILE_SIZE_X == 0U);
    dim3 const block_dim{NUM_THREADS_PER_BLOCK, 1U, 1U};
    dim3 const grid_dim{
        (static_cast<unsigned int>(n) + BLOCK_TILE_SIZE_X - 1U) /
            BLOCK_TILE_SIZE_X,
        (static_cast<unsigned int>(m) + BLOCK_TILE_SIZE_Y - 1U) /
            BLOCK_TILE_SIZE_Y,
        1U};
    gemm_v03<T, BLOCK_TILE_SIZE_X, BLOCK_TILE_SIZE_Y, BLOCK_TILE_SIZE_K,
             THREAD_TILE_SIZE_Y><<<grid_dim, block_dim, 0U, stream>>>(
        m, n, k, *alpha, A, lda, B, ldb, *beta, C, ldc);
    CHECK_LAST_CUDA_ERROR();
}

👉参阅、更新:计算思维 | 亚图跨际

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2210709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BUUCTF-[2019红帽杯]easyRE(Reverse逆向)

第一步 查壳 如图&#xff0c;无壳&#xff0c;ELF文件 第二步 IDA 64位IDA&#xff0c;无法直定位到主函数F5&#xff0c;所以使用&#xff0c;查找关键字符串定位主函数大法ShiftF12 发现这些关键字符串&#xff0c;双击上图蓝色字符串&#xff0c; 然后交叉引用CtrlX跟踪 …

硬件-示波器-巧用触发功能捕捉不连续的信号波形

文章目录 一&#xff1a;使用示波器的信号触发功能二&#xff1a;介绍示波器触发模式界面2.1 触发模式的AUTO档2.2 触发模式的Normal档&#xff08;普通档&#xff09;2.3 触发模式的single档&#xff08;单次触发档&#xff09; 三&#xff1a;在多通道的情况下&#xff0c;选…

电鳗带来灵感,防潮电源诞生,全打印技术的魅力

大家好&#xff01;今天来了解一项受电鳗启发的防潮完全可打印电源的研究——《A moisture-enabled fully printable power source inspired by electric eels》发表于《PNAS》。随着可穿戴电子设备的发展&#xff0c;对安全、一次性且具成本效益的电源需求大增。传统电池存在不…

react native 与 react.js 的区别

React.js ReactJS是一个 JavaScript 库&#xff0c;支持前端 Web 和在服务器上运行&#xff0c;用于构建用户界面和 Web 应用程序。 它主要重点是Web 开发&#xff0c;遵循可重用组件的概念。 React 的虚拟 DOM 比传统的完全刷新模型更快&#xff0c;因为虚拟 DOM 只刷新页面的…

透过《当音乐停止之后》,理解2008年次贷危机:债务、流动性与资本的无声博弈

金融市场就像是整个经济体的循环系统&#xff0c;现代经济体依赖各种授信机制输送营养到整个系统&#xff0c;维持经济的正常运转。书中揭示了2008年次贷危机的背景&#xff0c;以及量化宽松&#xff08;QE&#xff09;政策的作用。通过作者的讲述&#xff0c;我们真正了解2008…

前端继承:原理、实现方式与应用场景

目录 一、定义 二、语法和实现方式 1.原型链继承 2.构造函数继承 3.组合继承 4.ES6类继承 三、使用方式 四、优点 五、缺点 六、适用场景 一、定义 前端继承是指在面向对象编程中&#xff0c;一个对象可以继承另一个对象的属性和方法。在前端领域&#xff0c;通常是指…

HC32F460KETA PETB JATA 工业 自动化 电机

HC32F460 系列是基于 ARM Cortex-M4 32-bit RISC CPU&#xff0c;最高工作频率 200MHz 的高性能 MCU。Cortex-M4 内核集成了浮点运算单元&#xff08;FPU&#xff09;和 DSP&#xff0c;实现单精度浮点算术运算&#xff0c;支持 所有 ARM 单精度数据处理指令和数据类型&#xf…

【精选】基于javaweb的流浪动物领养系统(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

centos系列图形化 VNC server配置,及VNC viewer连接,2024年亲测有效

centos系列图形化 VNC server配置&#xff0c;及VNC viewer连接 0.VNC服务介绍 VNC英文全称为Virtual Network Computing&#xff0c;可以位操作系统提供图形接口连接方式&#xff0c;简单的来说就是一款桌面共享应用&#xff0c;类似于qq的远程连接。该服务是基于C/S模型的。…

鸿蒙NEXT开发-知乎评论小案例(基于最新api12稳定版)

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

vue实现列表自动滚动(纯与原生方式)

Vue实现列表自动滚动(纯与原生方式) 源码放在最后&#xff01;1.效果展示: 2.功能说明: 该滚动可能存在的Bug&#xff1a; 1.如果你写的大屏不是使用的接口轮询的方式可能会存在也页面空白的情况(需要手动刷新才能触发列表滚动)&#xff0c;因为我使用的是监听数据的变化然后…

软件供应链十年:探索开源的增长、风险和未来

回顾软件供应链状况报告的 10 年既是一个里程碑&#xff0c;也是一次行动号召。在过去十年中&#xff0c;开源消费改变了软件开发的世界。我们看到了前所未有的创新&#xff0c;但也出现了新的挑战&#xff0c;特别是在管理软件供应链的安全性和完整性方面。 在 Sonatype&…

基于SpringBoot民宿预订系统小程序【附源码】

效果如下&#xff1a; 管理员登录界面 管理员功能界面 用户管理界面 房东管理界面 小程序首页界面 民宿房间界面 功能界面 研究背景 随着旅游业的蓬勃发展和人们对旅行体验的不断追求&#xff0c;民宿作为一种独特的住宿方式&#xff0c;因其个性化、温馨及富含地方特色的服务…

disabled状态el-form下el-button的disabled的精细化控制

有一个很复杂的表单&#xff0c;支持编辑和查看两种模式。 查看时当然不希望编辑&#xff0c;最好是区分模式&#xff0c;在编辑模式下直接用div显示而不是用表单元素。这样工作量就有点大。那就考虑使用表单元素的disabled来让其不能编辑。如果每个表单元素都写这个玩意也是…

ssm职业高中学情成绩系统设计+jsp

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 摘 要 I Abstract II 第一章 绪论 1 1.1 研究背景 1 1.2 研究意义 1 1.3 研究内容 2 第二章 开发环…

codeforces round976 div2

A find minimum operations 思路&#xff1a;将所给的n变成k进制数&#xff0c;答案就是n的k进制形式下的位数之和 代码&#xff1a; #include <bits/stdc.h> using namespace std;typedef long long ll;ll n, k;void solve() {cin >> n >> k;ll cnt 0…

详解Spotbugs-maven-plugin(报告如何生成html测试报告)

Spotbugs介绍 SpotBugs是Findbugs的继任者&#xff08;Findbugs已经不再维护&#xff09;&#xff0c;用于对Java代码进行静态分析&#xff0c;查找相关的漏洞&#xff0c;SpotBugs比Findbugs拥有更多的校验规则。静态分析会检查Java字节码&#xff08;.class文件&#xff09;…

专题十一_递归_回溯_剪枝_综合练习_算法专题详细总结

目录 1. 找出所有⼦集的异或总和再求和&#xff08;easy&#xff09; 解析&#xff1a; 方法一&#xff1a; 解法二&#xff1a; 总结&#xff1a; 2. 全排列 Ⅱ&#xff08;medium&#xff09; 解析&#xff1a; 解法一&#xff1a;只关心“不合法”的分支 解法二&…

AI比诺奖得主更聪明。。。

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 AI圈又发生了哪些新鲜事&#xff1f; 特斯拉Optimus人形机器人亮相&#xff1a;日常任务好帮手 特斯拉在Cybercab活动上展示了其新款人形机器人Optimus&#xff0c;这款机器人能够执行拿包裹、浇水等…

CentOS快速配置网络Docker快速部署

CentOS快速配置网络&&Docker快速部署 CentOS裸机Docker部署1.联通外网2.配置CentOS镜像源3.安装Docker4.启动Docker5.CentOS7安装DockerCompose Bug合集ERROR [internal] load metadata for docker.io/library/java:8-alpineError: Could not find or load main class …