精华内容
下载资源
问答
  • png选项 无交错 交错 什么是交错内存? (What is Interleaved Memory?) It is a technique for compensating the relatively slow speed of DRAM(Dynamic RAM). In this technique, the main memory is divided ...

    png选项 无交错 交错

    It is a technique for compensating the relatively slow speed of DRAM(Dynamic RAM). In this technique, the main memory is divided into memory banks which can be accessed individually without any dependency on the other.

    它是一种用于补偿DRAM(动态RAM)相对较慢的速度的技术。 在这种技术中,主存储器被划分为多个存储体,这些存储体可以独立访问而彼此之间没有任何依赖性。

    For example: If we have 4 memory banks(4-way Interleaved memory), with each containing 256 bytes, then, the Block Oriented scheme(no interleaving), will assign virtual address 0 to 255 to the first bank, 256 to 511 to the second bank. But in Interleaved memory, virtual address 0 will be with the first bank, 1 with the second memory bank, 2 with the third bank and 3 with the fourt, and then 4 with the first memory bank again.

    例如:如果我们有4个存储区(4路交错存储),每个存储区包含256个字节,则面向块的方案(无交织)将为第一个存储区分配虚拟地址0至255,将256至511分配给虚拟地址。第二银行。 但是在交错存储器中,虚拟地址0将与第一个存储体一起使用,1与第二个存储体一起存储,2与第三个存储体一起使用,3与Fourt一起存储,然后4与第一个存储体一起使用。

    Hence, CPU can access alternate sections immediately without waiting for memory to be cached. There are multiple memory banks which take turns for supply of data.

    因此,CPU可以立即访问备用段,而无需等待内存被缓存。 有多个存储库轮流提供数据。

    Memory interleaving is a technique for increasing memory speed. It is a process that makes the system more efficient, fast and reliable.

    内存交错是一种提高内存速度的技术。 这是使系统更加高效,快速和可靠的过程。

    For example: In the above example of 4 memory banks, data with virtual address 0, 1, 2 and 3 can be accessed simultaneously as they reside in spearate memory banks, hence we do not have to wait for completion of a data fetch, to begin with the next.

    例如:在上面的4个存储体示例中,虚拟地址为0、1、2和3的数据由于驻留在矛状存储体中,因此可以同时访问,因此我们不必等待数据提取完成即可。从下一个开始。

    An interleaved memory with n banks is said to be n-way interleaved. In an interleaved memory system, there are still two banks of DRAM but logically the system seems one bank of memory that is twice as large.

    具有n个存储体的交错存储器被称为n路交错 。 在交错存储系统中,仍然有两排DRAM,但从逻辑上讲,该系统似乎是一块两倍大的内存。

    In the interleaved bank representation below with 2 memory banks, the first long word of bank 0 is floowed by that of bank 1, which is followed by the second long word of bank 0, which is followed by the second long word of bank 1 and so on.

    在下面的带有2个存储体的交错存储体表示中,存储体0的第一个长字与存储体1的相移,其后是存储体0的第二个长字,其后是存储体1的第二个长字和以此类推。

    The following figure shows the organization of two physical banks of n long words. All even long words of logical bank are located in physical bank 0 and all odd long words are located in physical bank 1.

    下图显示了n个长字的两个物理银行的组织。 逻辑存储区的所有偶数长字都位于物理存储区0中,所有奇数长字都位于物理存储区1中。

    Interleaved Memory

    交织类型 (Types of Interleaving)

    There are two methods for interleaving a memory:

    有两种交错存储的方法:

    2路交错 (2-Way Interleaved)

    Two memory blocks are accessed at same time for writing and reading operations.

    同时访问两个存储块以进行写入和读取操作。

    4路交错 (4-Way Interleaved)

    Four memory blocks are accessed at the same time.

    可以同时访问四个存储块。

    翻译自: https://www.studytonight.com/computer-architecture/interleaved-memory

    png选项 无交错 交错

    展开全文
  • CUDA优化实例(三)共享内存

    千次阅读 2018-03-11 21:52:48
    CUDA优化实例(三)共享内存 前言 经过前面的实验发现,共享内存是优化CUDA程序的...可以用合并的方式将块要操作的数据写入共享内存,让复杂的内存交错访问访问共享内存,然后将结果以合并的方式写入全局内存。 ...

    CUDA优化实例(三)共享内存

    前言

    经过前面的实验发现,共享内存是优化CUDA程序的核心方法。共享内存可以通过对全局内存数据进行合并访问,让kernel内交错的内存需求去访问共享内存。如:矩阵转置问题,将二维内存的行写入二维内存的列。对列的写入就是一个内存交错访问的例子。可以用合并的方式将块要操作的数据写入共享内存,让复杂的内存交错访问访问共享内存,然后将结果以合并的方式写入全局内存。
    在使用共享内存时需要注意

    1. 共享内存是服务于块的,所以一般要注意同步即__syncthreads() 的使用。
    2. 共享内存对复杂的内存处理有优势是因为它被分为32个内存存储体,而32个内存存储体可同时被访问,即内存请求分布在不同的内存存储体上的话,会同时获得该数据,但请求在同一(行)内存存储体上的话,速度会受影响。填充是一种克服内存存储体冲突的方法,下面会介绍。
    3. 每个共享内存存储体的宽可以是32位或64位,即4字节和8字节,用于对付单精度和双精度的数据。一般情况下,我们认为我们的每个kernel只处理一个数据只处理4字节的单精度或8字节的双精度,这样一个线程束的32个线程纠正好与32个(32个说成,一行更准确)内存存储体的大小一样都是128b,这样如果不存在内存体冲突,只需要一个共享内存访问事务,反之则需要多个。共享内存资源处理单精度的数据默认存储体宽度的32位即可,若处理双精度,为了不浪费稀有的共享内存资源,显式的定义宽度为64位。
    4. 共享内存是稀缺的SM上的资源,所以它会影响块在SM上的分布,影响占用率,计算一下每个块共享的低下限。对于存储体32位情况:我的GTX1050Ti 每个SM的共享内存大小是48KB,如果保证占用率的话,每个SM最多可容纳16个块,也就是每个块可以最多分配48KB/16 = 3KB的空间,换算到768个单精度的浮点数据。也就是说一个块最多可以申请768个4字节的数据,如果超过这个空间的大小,那么不能保证所有SM中有16个块,不能保证占用率。(提一下寄存器资源2048个线程运行时,每个线程32字节)

      实验:

      此实验是在NVIDIA官方找的一个例子

      代码:

        /* Copyright (c) 1993-2015, NVIDIA CORPORATION. All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *  * Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *  * Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *  * Neither the name of NVIDIA CORPORATION nor the names of its
     *    contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <stdio.h>
    #include <assert.h>
    
    // Convenience function for checking CUDA runtime API results
    // can be wrapped around any runtime API call. No-op in release builds.
    inline
    cudaError_t checkCuda(cudaError_t result)
    {
    #if defined(DEBUG) || defined(_DEBUG)
      if (result != cudaSuccess) {
        fprintf(stderr, "CUDA Runtime Error: %s\n", cudaGetErrorString(result));
        assert(result == cudaSuccess);
      }
    #endif
      return result;
    }
    
    const int TILE_DIM = 32;
    const int BLOCK_ROWS = 8;
    const int NUM_REPS = 100;
    
    // Check errors and print GB/s
    void postprocess(const float *ref, const float *res, int n, float ms)
    {
      bool passed = true;
      for (int i = 0; i < n; i++)
        if (res[i] != ref[i]) {
          printf("%d %f %f\n", i, res[i], ref[i]);
          printf("%25s\n", "*** FAILED ***");
          passed = false;
          break;
        }
      if (passed)
        printf("%20.2f\n", 2 * n * sizeof(float) * 1e-6 * NUM_REPS / ms );
    }
    
    // simple copy kernel
    // Used as reference case representing best effective bandwidth.
    __global__ void copy(float *odata, const float *idata)
    {
      int x = blockIdx.x * TILE_DIM + threadIdx.x;
      int y = blockIdx.y * TILE_DIM + threadIdx.y;
      int width = gridDim.x * TILE_DIM;
    
      for (int j = 0; j < TILE_DIM; j+= BLOCK_ROWS)
        odata[(y+j)*width + x] = idata[(y+j)*width + x];
    }
    
    // copy kernel using shared memory
    // Also used as reference case, demonstrating effect of using shared memory.
    __global__ void copySharedMem(float *odata, const float *idata)
    {
      __shared__ float tile[TILE_DIM * TILE_DIM];
    
      int x = blockIdx.x * TILE_DIM + threadIdx.x;
      int y = blockIdx.y * TILE_DIM + threadIdx.y;
      int width = gridDim.x * TILE_DIM;
    
      for (int j = 0; j < TILE_DIM; j += BLOCK_ROWS)
         tile[(threadIdx.y+j)*TILE_DIM + threadIdx.x] = idata[(y+j)*width + x];
    
      __syncthreads();
    
      for (int j = 0; j < TILE_DIM; j += BLOCK_ROWS)
         odata[(y+j)*width + x] = tile[(threadIdx.y+j)*TILE_DIM + threadIdx.x];          
    }
    
    // naive transpose
    // Simplest transpose; doesn't use shared memory.
    // Global memory reads are coalesced but writes are not.
    __global__ void transposeNaive(float *odata, const float *idata)
    {
      int x = blockIdx.x * TILE_DIM + threadIdx.x;
      int y = blockIdx.y * TILE_DIM + threadIdx.y;
      int width = gridDim.x * TILE_DIM;
    
      for (int j = 0; j < TILE_DIM; j+= BLOCK_ROWS)
        odata[x*width + (y+j)] = idata[(y+j)*width + x];
    }
    
    // coalesced transpose
    // Uses shared memory to achieve coalesing in both reads and writes
    // Tile width == #banks causes shared memory bank conflicts.
    __global__ void transposeCoalesced(float *odata, const float *idata)
    {
      __shared__ float tile[TILE_DIM][TILE_DIM];
    
      int x = blockIdx.x * TILE_DIM + threadIdx.x;
      int y = blockIdx.y * TILE_DIM + threadIdx.y;
      int width = gridDim.x * TILE_DIM;
    
      for (int j = 0; j < TILE_DIM; j += BLOCK_ROWS)
         tile[threadIdx.y+j][threadIdx.x] = idata[(y+j)*width + x];
    
      __syncthreads();
    
      x = blockIdx.y * TILE_DIM + threadIdx.x;  // transpose block offset
      y = blockIdx.x * TILE_DIM + threadIdx.y;
    
      for (int j = 0; j < TILE_DIM; j += BLOCK_ROWS)
         odata[(y+j)*width + x] = tile[threadIdx.x][threadIdx.y + j];
    }
    
    
    // No bank-conflict transpose
    // Same as transposeCoalesced except the first tile dimension is padded 
    // to avoid shared memory bank conflicts.
    __global__ void transposeNoBankConflicts(float *odata, const float *idata)
    {
      __shared__ float tile[TILE_DIM][TILE_DIM+1];
    
      int x = blockIdx.x * TILE_DIM + threadIdx.x;
      int y = blockIdx.y * TILE_DIM + threadIdx.y;
      int width = gridDim.x * TILE_DIM;
    
      for (int j = 0; j < TILE_DIM; j += BLOCK_ROWS)
         tile[threadIdx.y+j][threadIdx.x] = idata[(y+j)*width + x];
    
      __syncthreads();
    
      x = blockIdx.y * TILE_DIM + threadIdx.x;  // transpose block offset
      y = blockIdx.x * TILE_DIM + threadIdx.y;
    
      for (int j = 0; j < TILE_DIM; j += BLOCK_ROWS)
         odata[(y+j)*width + x] = tile[threadIdx.x][threadIdx.y + j];
    }
    
    int main(int argc, char **argv)
    {
      const int nx = 1024;
      const int ny = 1024;
      const int mem_size = nx*ny*sizeof(float);
    
      dim3 dimGrid(nx/TILE_DIM, ny/TILE_DIM, 1);
      dim3 dimBlock(TILE_DIM, BLOCK_ROWS, 1);
    
      int devId = 0;
      if (argc > 1) devId = atoi(argv[1]);
    
      cudaDeviceProp prop;
      checkCuda( cudaGetDeviceProperties(&prop, devId));
      printf("\nDevice : %s\n", prop.name);
      printf("Matrix size: %d %d, Block size: %d %d, Tile size: %d %d\n", 
             nx, ny, TILE_DIM, BLOCK_ROWS, TILE_DIM, TILE_DIM);
      printf("dimGrid: %d %d %d. dimBlock: %d %d %d\n",
             dimGrid.x, dimGrid.y, dimGrid.z, dimBlock.x, dimBlock.y, dimBlock.z);
    
      checkCuda( cudaSetDevice(devId) );
    
      float *h_idata = (float*)malloc(mem_size);
      float *h_cdata = (float*)malloc(mem_size);
      float *h_tdata = (float*)malloc(mem_size);
      float *gold    = (float*)malloc(mem_size);
    
      float *d_idata, *d_cdata, *d_tdata;
      checkCuda( cudaMalloc(&d_idata, mem_size) );
      checkCuda( cudaMalloc(&d_cdata, mem_size) );
      checkCuda( cudaMalloc(&d_tdata, mem_size) );
    
      // check parameters and calculate execution configuration
      if (nx % TILE_DIM || ny % TILE_DIM) {
        printf("nx and ny must be a multiple of TILE_DIM\n");
        goto error_exit;
      }
    
      if (TILE_DIM % BLOCK_ROWS) {
        printf("TILE_DIM must be a multiple of BLOCK_ROWS\n");
        goto error_exit;
      }
    
      // host
      for (int j = 0; j < ny; j++)
        for (int i = 0; i < nx; i++)
          h_idata[j*nx + i] = j*nx + i;
    
      // correct result for error checking
      for (int j = 0; j < ny; j++)
        for (int i = 0; i < nx; i++)
          gold[j*nx + i] = h_idata[i*nx + j];
    
      // device
      checkCuda( cudaMemcpy(d_idata, h_idata, mem_size, cudaMemcpyHostToDevice) );
    
      // events for timing
      cudaEvent_t startEvent, stopEvent;
      checkCuda( cudaEventCreate(&startEvent) );
      checkCuda( cudaEventCreate(&stopEvent) );
      float ms;
    
      // ------------
      // time kernels
      // ------------
      printf("%25s%25s\n", "Routine", "Bandwidth (GB/s)");
    
      // ----
      // copy 
      // ----
      printf("%25s", "copy");
      checkCuda( cudaMemset(d_cdata, 0, mem_size) );
      // warm up
      copy<<<dimGrid, dimBlock>>>(d_cdata, d_idata);
      checkCuda( cudaEventRecord(startEvent, 0) );
      for (int i = 0; i < NUM_REPS; i++)
         copy<<<dimGrid, dimBlock>>>(d_cdata, d_idata);
      checkCuda( cudaEventRecord(stopEvent, 0) );
      checkCuda( cudaEventSynchronize(stopEvent) );
      checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
      checkCuda( cudaMemcpy(h_cdata, d_cdata, mem_size, cudaMemcpyDeviceToHost) );
      postprocess(h_idata, h_cdata, nx*ny, ms);
    
      // -------------
      // copySharedMem 
      // -------------
      printf("%25s", "shared memory copy");
      checkCuda( cudaMemset(d_cdata, 0, mem_size) );
      // warm up
      copySharedMem<<<dimGrid, dimBlock>>>(d_cdata, d_idata);
      checkCuda( cudaEventRecord(startEvent, 0) );
      for (int i = 0; i < NUM_REPS; i++)
         copySharedMem<<<dimGrid, dimBlock>>>(d_cdata, d_idata);
      checkCuda( cudaEventRecord(stopEvent, 0) );
      checkCuda( cudaEventSynchronize(stopEvent) );
      checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
      checkCuda( cudaMemcpy(h_cdata, d_cdata, mem_size, cudaMemcpyDeviceToHost) );
      postprocess(h_idata, h_cdata, nx * ny, ms);
    
      // --------------
      // transposeNaive 
      // --------------
      printf("%25s", "naive transpose");
      checkCuda( cudaMemset(d_tdata, 0, mem_size) );
      // warmup
      transposeNaive<<<dimGrid, dimBlock>>>(d_tdata, d_idata);
      checkCuda( cudaEventRecord(startEvent, 0) );
      for (int i = 0; i < NUM_REPS; i++)
         transposeNaive<<<dimGrid, dimBlock>>>(d_tdata, d_idata);
      checkCuda( cudaEventRecord(stopEvent, 0) );
      checkCuda( cudaEventSynchronize(stopEvent) );
      checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
      checkCuda( cudaMemcpy(h_tdata, d_tdata, mem_size, cudaMemcpyDeviceToHost) );
      postprocess(gold, h_tdata, nx * ny, ms);
    
      // ------------------
      // transposeCoalesced 
      // ------------------
      printf("%25s", "coalesced transpose");
      checkCuda( cudaMemset(d_tdata, 0, mem_size) );
      // warmup
      transposeCoalesced<<<dimGrid, dimBlock>>>(d_tdata, d_idata);
      checkCuda( cudaEventRecord(startEvent, 0) );
      for (int i = 0; i < NUM_REPS; i++)
         transposeCoalesced<<<dimGrid, dimBlock>>>(d_tdata, d_idata);
      checkCuda( cudaEventRecord(stopEvent, 0) );
      checkCuda( cudaEventSynchronize(stopEvent) );
      checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
      checkCuda( cudaMemcpy(h_tdata, d_tdata, mem_size, cudaMemcpyDeviceToHost) );
      postprocess(gold, h_tdata, nx * ny, ms);
    
      // ------------------------
      // transposeNoBankConflicts
      // ------------------------
      printf("%25s", "conflict-free transpose");
      checkCuda( cudaMemset(d_tdata, 0, mem_size) );
      // warmup
      transposeNoBankConflicts<<<dimGrid, dimBlock>>>(d_tdata, d_idata);
      checkCuda( cudaEventRecord(startEvent, 0) );
      for (int i = 0; i < NUM_REPS; i++)
         transposeNoBankConflicts<<<dimGrid, dimBlock>>>(d_tdata, d_idata);
      checkCuda( cudaEventRecord(stopEvent, 0) );
      checkCuda( cudaEventSynchronize(stopEvent) );
      checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
      checkCuda( cudaMemcpy(h_tdata, d_tdata, mem_size, cudaMemcpyDeviceToHost) );
      postprocess(gold, h_tdata, nx * ny, ms);
    
    error_exit:
      // cleanup
      checkCuda( cudaEventDestroy(startEvent) );
      checkCuda( cudaEventDestroy(stopEvent) );
      checkCuda( cudaFree(d_tdata) );
      checkCuda( cudaFree(d_cdata) );
      checkCuda( cudaFree(d_idata) );
      free(h_idata);
      free(h_tdata);
      free(h_cdata);
      free(gold);
    }

    结果

    共享内存

    性能由好到坏是:

    核函数名带宽
    copy95.42
    shared memory copy97.16
    conflict-free transpose94.90
    coalesced transpose53.72
    naive transpose27.81

    前三个基本一样。后面解释

    分析

    const int TILE_DIM = 32;
    const int BLOCK_ROWS = 8;
    const int NUM_REPS = 100;

    每个块只有32×8的大小,但其处理了32×32的数据,因为核函数中一下处理了4行,如下:

      for (int j = 0; j < TILE_DIM; j+= BLOCK_ROWS)
        odata[(y+j)*width + x] = idata[(y+j)*width + x];

    同时NUM_REPS是为了运行每个核函数100次并取平均带宽值作为结果

    各个核函数的含义:

    naive transpose:

    这是实现矩阵转置最朴素的方法,行访问列,其中行访问合并,但列访问不合并。它是所以性能的下限,即最差的情况。

      for (int j = 0; j < TILE_DIM; j+= BLOCK_ROWS)
        odata[x*width + (y+j)] = idata[(y+j)*width + x];
    copy:

    是理论带宽的最大值,它的读取和存储都是合并,是理论峰值。这问题是转置问题,存储合并不可能都是合并访问的,所以copy不是转置,而是简单的赋值或者叫复制,看check就看出来了,check的都是输入数组,它的作用是提供一个理论峰值作为参考。如下:都是原数组,没有转置。

     postprocess(h_idata, h_cdata, nx*ny, ms);
    shared memory copy:

    与copy函数一样,这个函数也是copy,只不过是使用shared memory去copy,是shared memory 合并访问全局内存,全局内存合并访问shared memory,这与是无法转置的,也是为了提供理论峰值。同时还可以做到控制变量。

    transposeCoalesced:

    此例是共享内存合并访问全局内存,全局内存非合并访问共享内存,由于全局内存写的时候访问的是一列数据,正好都在同一个内存存储体中,所以这是个内存存储体冲突较为严重的例子。但其性能还是较不使用共享内存高了很多。

    conflict-free transpose

    此例是共享内存合并访问全局内存,全局内存非合并访问共享内存,由于全局内存写的时候访问的是一列数据,该函数在共享内存后加了一列,达到了填充的目的:

      __shared__ float tile[TILE_DIM][TILE_DIM+1];

    填充:因为要访问的数据都是在一列,填充一列之后,要访问的数据就正好全部错开了,完全消除了存储体冲突,性能和合并一样好。

    1. 前三个性能一样是因为它们都是合并加载/存储全局变量都是理论峰值
    2. 填充在此例中是完美的被运用。

    结论

    共享内存对程序有很好的优化,但其运用也稍有些复杂,掌握好共享内存的最终目的是让全局内存被合并访问,达到最高的内存效率。

    展开全文
  • C#交错数组浅析

    2020-09-05 18:34:28
    里介绍C#交错数组,数组是具有同一类型的一组值,数组是引用类型的,因此存在内存堆中。数组中的元素值可以在定义数组时赋予,也可以在定义数组后对单个元素进行赋值
  • (2)空闲列表:java堆的内存是不完整的,用过的内存和没有用过的内存交错,虚拟机就必须来维护一个表,用来记录哪些内存是可以用的,在创建对象的时候直接在表中给分配相应的内存,并更新表。 ...

    java对象创建时在堆上内存划分的两种方法:

    (1)指针碰撞:java堆的内存是完整的,所有用过的内存放一边,没有用过的内存放一边,中间放着一个分隔的指针,有对象创建了,指针就向空闲处移动一定的内存区域。

    (2)空闲列表:java堆的内存是不完整的,用过的内存和没有用过的内存交错,虚拟机就必须来维护一个表,用来记录哪些内存是可以用的,在创建对象的时候直接在表中给分配相应的内存,并更新表。

    展开全文
  • c#交错数组

    2016-12-06 18:35:34
    交错数组是数组的数组,...声明一个数组不会在内存中创建数组,创建上面的数组 int [] [] scores=new int [5][]; for (int i=0;i { scores[i]=new int [4]; } 初始化交错数组 int [] [] scores=new int [2

    交错数组是数组的数组,可以声明一个带有int值的交错数组scores

    int [] [] scores;

    声明一个数组不会在内存中创建数组,创建上面的数组

    int [] [] scores=new int [5][];

    for (int i=0;i<scores.length;i++)

    {

    scores[i]=new int [4];

    }


    初始化交错数组

    int [] [] scores=new int [2][]{new int []{92,93,94},new int []{85,86,87,88}};

    其中,scores是一个由两个整型数组组成的数组--scores[0]是一个带有三个整数的数组,scores[1]是一个带有4个整数的数组

    using System;

    namespace ArrayApplication

    {

    class MyArray

    {

    static void Main(string [] args)

    {

    int [] [] a=new int [] []{new int [][]{0,0},new int [] {1,2},new int[] {2,4},new int []{3,6},new int []{4,8}};

    int i.j;

    for(i=0;i<5;i++)

    {

    for(j=0;j<2;j++)

    {

    Console.WriteLine("a[{0}][{1}]={2}",i,j,a[i][j]);

    }

    }

    Console.ReadKey();

    }

    }

    }

    展开全文
  • yuv420图片非交错转yvu420交错格式 C语言 linux系统 源码 简单工具类
  • C#交错数组

    2018-06-26 13:22:00
    交错数组定义:交错数组本质上是一维数组只不过这个一维数组里的元素都是一维数组。并且该一维数组里面的元素可以是任何大小的数组声明:int[][] array;(声明数组不占内存)初始化:1:int[][] array = { new int[] {...
  • 三个线程交错输出

    2014-11-14 19:42:54
    三个线程交错输出,java实验,当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。
  • 交错数组是元素为数组的数组。 特性 交错数组只有一个维度,但是那一维度中的元素本身就是数组。 可以混合使用交错数组和多维数组。 int[][,] MixArray4 = new int[2][,] {}; 起源 多维数组可能消耗大量内存。...
  • #1033 : 交错

    2016-03-26 22:26:58
    内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1 ...
  • 现在有很多人都在玩电击文库零境交错手游,不过有些小伙伴不大喜欢用手机玩游戏,不仅太费电且屏幕小,体验感太差。下面小编就给亲们介绍下电击文库零境交错怎么在电脑上玩手游哈! 一、前期准备工作 1、安卓...
  • 内存分配

    2017-02-08 18:16:21
    Java为对象分配空间的任务等同于把一块确定大小的内存从Java堆里面划分出来。 假设Java堆中内存是绝对的规整的,...假设Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那么就没有办法简单的进行指针
  • 内存Bank

    2014-08-22 01:35:04
    Bank (内存库) 在内存行业里,Bank至少有三种意思,所以一定要注意。 1、在SDRAM内存模组上,"bank 数"表示该内存的物理存储体的数量。(等同于"行"/Row) 2、Bank还表示一个SDRAM设备内部的逻辑存储库的...
  • 现有的频率域波全形反演多是默认基于正方形旋转交错网格,而基于矩形旋转交错网格的全波形反演有更大的灵活性,能更好地适应实际地下介质结构,有更好的内存使用率和计算效率。为了解决原始的基于正方形网格的PML...
  • 但对于交错 GridLayoutManager。 我试图从这个很好的答案中编辑代码:public class StaggeredGridAutofitLayoutManager extends StaggeredGridLayoutManager {private int mColumnWidth;private boolean ...
  • 多维数组与交错数组

    2017-12-01 21:18:43
    //两行三列的数组我们知道一维数组在内存中是占据一个线性的空间。而且数组有一个特点,也可以说是缺点,那就是数组一旦分配之后,长度就是确定的。对于二维数组来说亦同,二维数组在内存中占据的,其实也是一个...
  • 交错原理介绍

    千次阅读 2011-09-30 17:25:25
    交错亦称“反交错”(deinterlacing)是将交错式(即隔行扫描)(interlace)影像讯号转换为渐进式(逐行扫描)(progressive)影像讯号的一种方法。 因为装置处理速度以及带宽的限制下,广播电视系统,例如NTSC...
  • hihocoder 1033 交错

    2015-05-04 18:34:17
    内存限制:256MB描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, …, an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - … + ( - 1)^[n - 1]*an - 1 例如: f(3214567...
  • HihoCoder 1033:交错

    2016-02-18 13:57:03
    内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1 例如: f...
  • Java内存区域与内存溢出

    千次阅读 2020-02-09 17:27:55
    在C语言中,开发者需要维护对象的出生和死亡,往往需要为每个new出来的对象编写配套的delete/free代码来释放内存,否则可能发生内存泄漏或溢出。 而在Java中,内存由JVM管理,垃圾回收器GC会帮助开发者自动回收不再...
  • JVM内存管理备忘

    2017-03-22 10:12:43
    为对象分配内存就是把一块大小确定的内存从堆内存中划分出来,通常有两种方法实现:1 、指针碰撞法假设Java堆中内存时完整的,已分配的内存和空闲内存分别在不同的一侧,通过一个指针作为分界点,需要分配内存
  • 视频处理——去交错原理

    千次阅读 2019-03-20 13:05:35
    交错亦称“反交错”(deinterlacing)是将交错式(即隔行扫描)(interlace)影像讯号转换为渐进式(逐行扫描)(progressive)影像讯号的一种方法。 因为装置处理速度以及带宽的限制下,广播电视系统,例如NTSC...
  • 内存访问重新排序,以提高存储设备的性能一封FF ective方式。 通过更改访问的调度顺序,可以大大提高数据总线的利用率和带宽。 本文提出了一种嵌入式系统的突发交错调度(BIS)访问重排序机制。 它将定向到存储体同...
  • 思维导图 对象的创建 对象的内存布局 对象头( Header ) ...在 JVM-01自动内存管理机制之Java内存区域与内存溢出异常(上)中我们介绍了 运行时数据区域,这里我们来继续探讨下hotspot虚拟机对象 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,929
精华内容 7,171
关键字:

内存交错