精华内容
下载资源
问答
  • 为了扩内存,新装了64位的win7,结果开机到了1分多钟,是否跟扩内存有关系呢,求教。。。。。 我的本本是gateway的,原来的内存是2G的,刚装完系统的时候(没有加新内存的时候)开机挺快的,后来装了新内存以及其他...
  • 问题:将单节点的内存从512M加到4096M时运行时间不减少反而增加,不解,待解决。是不是单个测试用例的偶然性? hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster.sh fq0.count:105887

    问题:将单节点的内存从512M加到4096M时运行时间不减少反而增加,不解,待解决。是不是单个测试用例的偶然性?

    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster.sh 
    fq0.count:105887                                                                
    Method 1=> Length:2971 sum:7888989 time:26936ms
    Method 2=> Length:2971 sum2:7888989 time:2367ms
    Method 3=> Length:2971 sum3:7888989.0 time:4200ms
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ cp cluster.sh submit.sh
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ mv submit.sh cluster4G.sh 
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ vi cluster4G.sh 
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster4G.sh 
    fq0.count:105887                                                                
    Method 1=> Length:2971 sum:7888989 time:34320ms
    Method 2=> Length:2971 sum2:7888989 time:3078ms
    Method 3=> Length:2971 sum3:7888989.0 time:4136ms
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ 
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ 
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster4G.sh 
    fq0.count:105887                                                                
    Method 1=> Length:2971 sum:7888989 time:27065ms
    Method 2=> Length:2971 sum2:7888989 time:2764ms
    Method 3=> Length:2971 sum3:7888989.0 time:1292ms
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster
    -bash: ./cluster: No such file or directory
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster.sh 
    fq0.count:105887                                                                
    Method 1=> Length:2971 sum:7888989 time:24095ms
    Method 2=> Length:2971 sum2:7888989 time:4263ms
    Method 3=> Length:2971 sum3:7888989.0 time:4006ms
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ ./cluster4G.sh 
    fq0.count:105887                                                                
    Method 1=> Length:2971 sum:7888989 time:26671ms
    Method 2=> Length:2971 sum2:7888989 time:3404ms
    Method 3=> Length:2971 sum3:7888989.0 time:4196ms
    hadoop@Master:~/cloud/testByXubo/spark/hs38DH/package$ 
    



    集群:

    Application ID Name Cores Memory per Node Submitted Time User State Duration 
    app-20160417144715-0006  readFileFromHs38DH  12  4.0 GB  2016/04/17 14:47:15 hadoop FINISHED 47 s 
    app-20160417144235-0005  readFileFromHs38DH  12  512.0 MB  2016/04/17 14:42:35 hadoop FINISHED 40 s 
    app-20160417143730-0004  readFileFromHs38DH  12  4.0 GB  2016/04/17 14:37:30 hadoop FINISHED 44 s 
    app-20160417143619-0003  readFileFromHs38DH  12  4.0 GB  2016/04/17 14:36:19 hadoop FINISHED 51 s 
    app-20160417143459-0002  readFileFromHs38DH  12  512.0 MB  2016/04/17 14:34:59 hadoop FINISHED 42 s 



    展开全文
  • 这个问题已经困扰我很长时间,为此我也进行了基于几种设想的测试,尝试找到单双通道内存影响图灵显卡游戏表现的原因。以下提到的图灵显卡,均为笔记本中的图灵显卡。发现这个现象后,我综合已有的资料和外界声音,...

    这个问题已经困扰我很长时间,为此我也进行了基于几种设想的测试,尝试找到单双通道内存影响图灵显卡游戏表现的原因。以下提到的图灵显卡,均为笔记本中的图灵显卡。

    774d711bdb174481d6ca7266cbe1c635.png

    发现这个现象后,我综合已有的资料和外界声音,提出了四种可能导致这种现象的设想,分别为:GDDR6显存、英特尔CPU内存控制器、游戏以及图灵架构。针对这四种设想,我综合此前进行的部分测试,然后新增几项测试,尝试找到其中原因。

    GDDR6显存

    包括RTX显卡和GTX1660Ti在内的图灵显卡均采用GDDR6显存,之所以将GDDR6显存视为可能影响的一个原因,很大程度上是因为GDDR6显存相比GDDR5显存的变化在于,其采用了双通道读写设计。猜测GDDR6显存在与双通道内存搭配时数据传输可能更快,所以会影响到游戏帧数。针对这个猜想,我使用搭载GTX 1650 Max-Q的笔记本进行测试。GTX 1650 Max-Q是目前针对笔记本平台的图灵架构显卡中采用GDDR5显存的显卡,可以验证这个猜想。

    3deccc7bab9dcc0ebfe6ffa7866c19df.png

    GDDR6显存

    从测试数据来看,搭载GTX 1650 Max-Q的笔记本在运行《孤岛惊魂:新曙光》、《刺客信条:奥德赛》和《古墓丽影:暗影》的Benchmark时,依旧存在双通道内存下游戏帧数更高的情况,而且领先幅度在10%左右,非测试误差。

    007a136a94c6c9fc9acf04fec56a1b7e.png

    GTX 1650 Max-Q单双通道游戏帧数对比

    结果已经比较明显,即使采用GDDR5显存的图灵显卡GTX 1650 Max-Q同样存在单双通道内存影响游戏帧数的情况,可以确定GDDR6显存不是导致这种情况出现的原因。

    英特尔CPU内存控制器

    我发现部分网友认为八代/九代酷睿的内存控制器可能影响了单双通道下图灵显卡的游戏表现,所以将此列为可能的一个原因。目前不清楚网友提出该观点的理由,不过验证起来并不困难。我选择了两个配置的笔记本进行验证,首先是i7-8750H+GTX1050Ti,如果是CPU内存控制器的原因,那么理论上GTX10系显卡也会受影响;其次是锐龙7 3750H+GTX1660Ti Max-Q,如果是英特尔CPU内存控制器的原因,那么理论上GTX16系显卡不会受到影响。

    66ef21edd73cb4be0046d8639f545dd3.png

    不同平台单双通道游戏帧数对比

    从测试数据来看,运行《刺客信条:奥德赛》Benchmark时,GTX10系显卡并没有受英特尔八代酷睿的影响,双通道下测试帧数仅比单通道下高2帧,可视为误差;而即使搭配AMD处理器,GTX1660Ti Max-Q在单双通道内存下出现了较为明显的帧数差距,差距幅度高达40%,可见影响较为明显。

    从两组数据中可以看出,英特尔CPU内存控制器并不会影响图灵显卡在实际游戏中的表现,所以英特尔CPU内存控制器影响单双通道下图灵显卡的游戏表现的猜测并不成立。

    游戏

    是否因为不同游戏对单双通道内存有不同需求,导致最终游戏结果不同呢?毕竟不同游戏可能比较依赖显卡,也可能比较依赖CPU,也有游戏依赖内存。针对该猜想,我选用《刺客信条:奥德赛》和《地铁:离去》进行对比测试。

    ecc48100cdb04afb60fdeed2b1939b0f.png

    两款游戏依赖双通道内存程度不同

    从测试结果中可以看出,双通道内存下《刺客信条:奥德赛》这款游戏明显帧数更高,而且领先单通道内存下的幅度比较明显,最少也达到了17%;反观《地铁:离去》,该游戏对双通道内存依赖就比较低,领先幅度基本可以视作测试误差。

    130e609990e771857e1c490c0c4f3cf8.png

    GTX1050Ti受影响远低于RTX显卡

    难道《刺客信条:奥德赛》这么需要双通道内存吗?我又加入了GTX1050Ti显卡进行对比,从对比结果中可以看出,RTX显卡受双通道影响明显,但GTXGTX1050Ti在双通道内存下的游戏帧数提升仅为5%,相比RTX显卡提升并不是特别明显。

    从上述两组数据可以看出,部分游戏确实受双通道内存影响,双通道内存下游戏帧数更高一些,但领先幅度非常有限,领先幅度可能仅为5%左右,体现到帧数上可能只有两三帧;而图灵显卡却出现了领先幅度特别大的情况,部分游戏比如《刺客信条:奥德赛》领先幅度可达20%以上。

    所以可以得出这样的结论:不同游戏确实对单双通道内存有不同需求,但图灵显卡在运行受双通道影响的游戏时,双通道下的游戏帧数表现明显高于单通道,领先幅度过大。将原因单纯归结为游戏并不合适。

    图灵架构

    图灵架构是大家怀疑最多的,毕竟与GTX10系显卡相比,图灵架构变动较大,特别是加入的RT Core和Tensor Core是GTX10系显卡没有的。那么会不会是RT Core或Tensor Core产生影响呢?我选择了搭载GTX1660Ti的笔记本进行测试,GTX1660Ti为图灵架构,但没有RT Core和Tensor Core,可以验证该猜想。

    d4f1632c950c5097aa5281df689639da.png

    GTX1660Ti同样受双通道内存影响

    从测试数据可以看出,GTX1660Ti仍然受单双通道内存影响,而且影响幅度与RTX显卡基本一致,比如在《刺客信条:奥德赛》中,双通道下帧数提升高达26.5%。

    从该结果中可以看出,图灵架构中的RT Core和Tensor Core并不受单双通道内存影响。至此我猜测,图灵显卡在实际游戏中的帧数表现受单双通道内存影响,极大可能是因为图灵架构本身,同时与RT Core和Tensor Core没有关系。

    总结和建议

    从上述四项测试来看,可以排除GDDR6显存、英特尔CPU内存控制器和RT Core、Tensor Core是影响单双通道下图灵显卡实际游戏帧数的因素。

    其中部分游戏确实存在依赖双通道内存的情况,比如《刺客信条:奥德赛》等,但在图灵显卡平台上却表现出“过分”依赖,而在GTX10系显卡中却不存在这种情况。所以从目前测试数据推测,出现单双通道下实际游戏帧数大幅差距的原因,极大可能是图灵架构本身。

    a8050380d55085170c5eb5b58bb4c173.png

    图灵架构

    无论其中是何原因,现如今搭载图灵显卡的笔记本已经成为主流,所以建议大家准备购买图灵显卡笔记本时,如果有游戏需求,预算充足的情况下最好选择双通道内存版本,这样可以保证最佳游戏体验。预算不足的情况下,入门级图灵显卡笔记本可能没有双通道内存版本,可自行购买内存加装,现如今DDR4内存价格进一步下降,现在购买比较合适。

    展开全文
  • caffe ssd中输入图片大小对于内存使用和运行时间影响 一、内存使用  环境为caffe下以imagenet为样本集训练resnset网络。 在初始化生成lmdb的create_imagenet.sh脚本中,resize参数分别设置为256*256和512*512...
    caffe ssd中输入图片大小对于内存使用和运行时间的影响

    一、内存使用
            环境为caffe下以imagenet为样本集训练resnset网络。      
    在初始化生成lmdb的create_imagenet.sh脚本中,resize参数分别设置为256*256和512*512。
    #!/usr/bin/env sh
    # Create the imagenet lmdb inputs
    # N.B. set the path to the imagenet train + val data dirs
    set -e
    
    EXAMPLE=/home/chhuang/workspace/deep_learning/bvlc_alexnet
    DATA=/home/chhuang/workspace/deep_learning/data/imagenet
    TOOLS=/home/softwares/caffe-master/build/tools
    
    TRAIN_DATA_ROOT=/home/softwares/data/Imagenet/ILSVRC2012/ILSVRC2012_img_train/
    VAL_DATA_ROOT=/home/softwares/data/Imagenet/ILSVRC2012/ILSVRC2012_img_val/
    
    # Set RESIZE=true to resize the images to 256x256. Leave as false if images have
    # already been resized using another tool.
    RESIZE=true
    if $RESIZE; then
      RESIZE_HEIGHT=512             //这里改256和512
      RESIZE_WIDTH=512
    else
      RESIZE_HEIGHT=0
      RESIZE_WIDTH=0
    fi
    
    if [ ! -d "$TRAIN_DATA_ROOT" ]; then
      echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
      echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
           "where the ImageNet training data is stored."
      exit 1
    fi
    
    if [ ! -d "$VAL_DATA_ROOT" ]; then
      echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
      echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
           "where the ImageNet validation data is stored."
      exit 1
    fi
    
    echo "Creating train lmdb..."
    
    GLOG_logtostderr=1 $TOOLS/convert_imageset \
        --resize_height=$RESIZE_HEIGHT \
        --resize_width=$RESIZE_WIDTH \
        --shuffle \
        $TRAIN_DATA_ROOT \
        /home/softwares/data/Imagenet/ILSVRC2012/trainsmall.txt \
        /home/softwares/data/Imagenet/ILSVRC2012/ilsvrc12_train_small_lmdb
    
    
    echo "Done."

    随后运行caffe tools中的train,观察使用的内存情况。(由于考量的是最终在测试过程中的内存使用,所以选择的batch-size为1

    50层resnet下:
    输入图像lmdb为256*256的情况:
    Memory required for data:302796532

    输入图像lmdb512*512的情况:
    Memory required for data:1211780852
    512*512内存使用情况基本是256*256内存使用的4倍。这也与实际情况相符合。

    二、运行时间

    由于最终使用ssd结构,所以在ssd中测试一下不同输入图片大小对于运行时间的影响。
    在ssd下运行VGGnet VOC数据集相同网络结构,不同的是输入分别为300*300和500*500.
    运行在cpu下测试42张图片做detection。
    300*300的sh为:
    #!/bin/sh
    date
    sudo .build_release/examples/ssd/ssd_detect.bin models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300_iter_60000.caffemodel image.txt
    date
    

    其结果为:
    Script started on 2016年12月01日 星期四 09时46分34秒
    root@fox:~/ssd/caffe# sudo sh test300.sh 
    2016年 12月 01日 星期四 09:46:40 CST
    I1201 09:46:40.683648 16505 upgrade_proto.cpp:67] Attempting to upgrade input file specified using deprecated input fields: models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt
    I1201 09:46:40.683956 16505 upgrade_proto.cpp:70] Successfully upgraded file specified using deprecated input fields.
    W1201 09:46:40.683977 16505 upgrade_proto.cpp:72] Note that future Caffe releases will only support input layers and not input fields.
    I1201 09:46:40.685127 16505 net.cpp:58] Initializing net from parameters: 
    name: "VGG_VOC0712_SSD_300x300_deploy"
    state {
      phase: TEST
      level: 0
    }
    layer {
      name: "input"
      type: "Input"
      top: "data"
      input_param {
        shape {
          dim: 1
          dim: 3
          dim: 300
          dim: 300
        }
      }
    }
    layer {
      name: "conv1_1"
    //......  
    //......  
    //layers
    //.......
    //.......
    I1201 09:46:41.058290 16505 net.cpp:761] Ignoring source layer mbox_loss
    pic/testimg00001.jpg 4 0.022213 1147 33 1419 553
    pic/testimg00001.jpg 5 0.0262909 1001 329 1076 453
    pic/testimg00001.jpg 5 0.0216578 796 250 877 416
    pic/testimg00001.jpg 5 0.0152326 813 311 919 443
    pic/testimg00001.jpg 5 0.0121413 711 863 823 1027
    pic/testimg00001.jpg 5 0.0115996 933 277 1023 435
    pic/testimg00001.jpg 6 0.0315219 7 191 141 321
    pic/testimg00001.jpg 6 0.0190812 4 312 344 434
    pic/testimg00001.jpg 6 0.017554 8 259 347 387
    //........
    //........
    //检测结果
    
    //........
    //........
    pic/testimg00042.jpg 7 0.567194 22 44 1954 1045
    pic/testimg00042.jpg 15 0.0142565 1643 186 1907 888
    pic/testimg00042.jpg 15 0.0129933 1517 334 1665 537
    pic/testimg00042.jpg 15 0.0128657 1812 142 1924 347
    pic/testimg00042.jpg 15 0.0127175 999 229 1854 977
    pic/testimg00042.jpg 15 0.0125595 1746 152 1920 556
    pic/testimg00042.jpg 15 0.0100875 1708 112 1915 345
    pic/testimg00042.jpg 19 0.206236 -20 76 1929 1003
    pic/testimg00042.jpg 20 0.0203152 -20 76 1929 1003
    2016年 12月 01日 星期四 09:47:40 CST
    
    

    300*300下,测试42张图片时间从9:46:41-9:47:40总共用了59秒

    500*500的sh为:
    #!/bin/sh
    date
    sudo .build_release/examples/ssd/ssd_detect.bin models/VGGNet/VOC0712/SSD_500x500/deploy.prototxt models/VGGNet/VOC0712/SSD_500x500/VGG_coco_SSD_500x500_iter_200000.caffemodel image.txt
    date

    其结果为:
    Script started on 2016年12月01日 星期四 09时51分22秒
    root@fox:~/ssd/caffe# sh[K[Ksudo sh test500.sh 
    2016年 12月 01日 星期四 09:51:30 CST
    I1201 09:51:30.804812 16567 upgrade_proto.cpp:67] Attempting to upgrade input file specified using deprecated input fields: models/VGGNet/VOC0712/SSD_500x500/deploy.prototxt
    I1201 09:51:30.805297 16567 upgrade_proto.cpp:70] Successfully upgraded file specified using deprecated input fields.
    W1201 09:51:30.805342 16567 upgrade_proto.cpp:72] Note that future Caffe releases will only support input layers and not input fields.
    I1201 09:51:30.807884 16567 net.cpp:58] Initializing net from parameters: 
    name: "VGG_coco_SSD_500x500_deploy"
    state {
      phase: TEST
      level: 0
    }
    layer {
      name: "input"
      type: "Input"
      top: "data"
      input_param {
        shape {
          dim: 1
          dim: 3
          dim: 500
          dim: 500
        }
      }
    }
    layer {
      name: "conv1_1"
    
    //......  
    //......  
    //layers
    //.......
    //.......
    I1201 09:51:32.158409 16567 net.cpp:761] Ignoring source layer mbox_loss
    pic/testimg00001.jpg 1 0.698755 636 628 754 949
    pic/testimg00001.jpg 1 0.253025 1042 586 1140 874
    pic/testimg00001.jpg 1 0.238435 743 691 860 959
    pic/testimg00001.jpg 1 0.118032 1060 422 1259 888
    pic/testimg00001.jpg 1 0.0983797 684 677 818 971
    pic/testimg00001.jpg 1 0.0951707 713 634 771 724
    pic/testimg00001.jpg 1 0.0922268 1008 373 1037 439
    pic/testimg00001.jpg 1 0.0918469 923 521 1012 557
    pic/testimg00001.jpg 1 0.0912337 1119 361 1239 553
    
    //........
    //........
    //检测结果
    
    //........
    //........
    
    pic/testimg00042.jpg 74 0.0312432 1747 396 1800 439pic/testimg00042.jpg 74 0.0304748 1842 389 1907 462pic/testimg00042.jpg 74 0.0272788 1736 352 1925 423pic/testimg00042.jpg 74 0.0269475 1713 397 1787 439pic/testimg00042.jpg 76 0.0348364 1078 304 1143 365pic/testimg00042.jpg
     76 0.0292064 1120 308 1168 3632016年 12月 01日 星期四 09:54:34 CST
    
    
    
    
    
    
    

    500*500下,测试42张图片从9:51:32-9:54:34总共用了182秒。

    500*500的图像尺寸是300*300的(500*500)/(300*300)=2.778倍,所用时间是182/59=3.085倍,时间影响大致与尺寸成1:1关系。

    展开全文
  • 因为要测试多组数据的运行时间,需要实现一个清空(destroy)操作。本着避免一切可能造成的内存泄漏,一开始我写了完整的清空函数,也就是从根节点开始递归,回收每个结点的内存空间,其中我的结点和树定义如下。 enum...

    起因是这样的,最近算法课在上红黑树,写红黑树的时候肯定涉及一些内存管理的问题,主要是在插入结点的时候要用new分配一个新的结点,并在清空红黑树的时候把这些结点delete释放掉。

    算法导论书上只提供了插入和删除操作的代码,但是因为要测试多组数据的运行时间,需要自己实现一个清空(destroy)操作。本着避免一切可能造成的内存泄漏的原则,一开始我写了完整的清空函数,也就是从根节点开始递归,回收每个结点的内存空间,其中我的结点和树定义如下。

    enum RBTColor{RED, BLACK};
    
    class RBTNode {
    public:
        RBTColor color;
        int key;
        RBTNode *lson;
        RBTNode *rson;
        RBTNode *parent;
        RBTNode(RBTColor c, int k) {
            color = c;
            key = k;
            lson = rson = parent = NULL;
        }
    };
    class RBTree {
    public:
        RBTree() {
            root = NULL;
        }
        void destroy() {
            destroy(root);
        }
    private:
        void destroy(RBTNode *&root) {
            if (root == NULL) return ;
            if (root->lson) destroy(root->lson);
            if (root->rson) destroy(root->rson);
            delete root;
            root = NULL;
        }
    }rb_tree;
    

    然而运行时感觉运行时间很奇怪,于是修改测试数据,测了5组规模一样的数据,发现只有第一次的运行时间是正常的,后面四次的时间明显大很多。进一步记录了一下destroy函数所占用的时间,结果如下。

    destroy time : 0 ms SIZE : 100000 RUNTIME : 71 ms
    destroy time : 46 ms SIZE : 100000 RUNTIME : 3308 ms
    destroy time : 38 ms SIZE : 100000 RUNTIME : 2442 ms
    destroy time : 38 ms SIZE : 100000 RUNTIME : 3415 ms
    destroy time : 39 ms SIZE : 100000 RUNTIME : 2267 ms
    destroy time : 38 ms
    

    意识到可能是destroy的过程中的某些操作产生了这样的结果,采取控制变量法,尝试去掉了内存回收的部分之后运行时间时间恢复正常。修改后的destroy和测试结果如下,但很明显,这样写又会有内存泄漏的问题,即没有在清空红黑树前回收每个结点的内存

    void destroy() {
        // clock_t rec = clock();
        // destroy(root);
        // cout << "destroy time : " << clock() - rec << " ms ";
        root = NULL;
    }
    
    SIZE : 100000 RUNTIME : 61 ms
    SIZE : 100000 RUNTIME : 64 ms
    SIZE : 100000 RUNTIME : 71 ms
    SIZE : 100000 RUNTIME : 67 ms
    SIZE : 100000 RUNTIME : 65 ms
    

    可以确定是清空操作(destroy)造成了这一现象。此时我陷入了疑惑:RUNTIME所记录的仅仅是执行红黑树“插入”操作所消耗的时间,并没有记录清空操作的时间,与清空操作唯一的联系是对于内存的操作。但清空操作完成后,此时红黑树的根结点指针指向空结点,整个程序的执行状态和程序刚开始时几乎完全相同,但实际运行时间却差了40-50倍。

    一个猜想是清空时的delete操作影响到了程序所能够使用的内存空间,但delete是起到回收内存的作用的,理论上来说意味着可供使用的内存空间更大了,为什么会比不回收内存空间的写法耗时更久呢?这一猜想完全不能解释这种现象。

    以上就是我目前遇到的最主要的问题,对此我还做了以下尝试:

    1. 修改测试数据规模大小,测试了10^6的情况,仍有这个问题

      destroy time : 0 ms SIZE : 1000000 RUNTIME : 669 ms
      destroy time : 470 ms SIZE : 1000000 RUNTIME : 7070 ms
      destroy time : 462 ms SIZE : 1000000 RUNTIME : 7294 ms
      destroy time : 473 ms SIZE : 1000000 RUNTIME : 7754 ms
      destroy time : 471 ms SIZE : 1000000 RUNTIME : 6117 ms
      destroy time : 468 ms
      
    2. 把释放内存的部分写到了RBTNode的析构函数中,并修改对应的destroy:

      class RBTNode {
      public:
          RBTColor color;
          int key;
          RBTNode *lson;
          RBTNode *rson;
          RBTNode *parent;
          RBTNode(RBTColor c, int k) {
              color = c;
              key = k;
              lson = rson = parent = NULL;
          }
          ~RBTNode() {
              if (lson) delete(lson); lson = NULL;
              if (rson) delete(rson); rson = NULL;
          }
      };
      void destroy() {
          clock_t rec = clock();
          delete(root);
          root = NULL;
          cout << "destroy time : " << clock() - rec << " ms ";
      }
      

      从结果来说,和原来的没有任何区别

    3. 写了一个简化版的测试程序,通过最简单的数据结构(链表)进行测试,问题仍然存在,可见不是红黑树操作的问题

      #include <bits/stdc++.h>
      
      using namespace std;
      
      int cnt;
      
      class Node {
      public:
          Node(int x) {
              key = x;
              nxt = NULL;
          }
          int key;
          Node *nxt;
      };
      
      class chain {
      public:
          chain() {
              head = NULL;
          }
          void destroy() {
              clock_t rec = clock();
              Node *now = head, *pre;
              while(now !=NULL && now->nxt != NULL) {
                  pre = now;
                  now = now->nxt;
                  delete pre;
                  pre = NULL;
                  cnt++;
              }
              if (now) delete now;
              head = NULL;
              cout << "destroy time : " << clock() - rec << " ms" << endl;
          }
          void insert(int x) {
              Node *node = new Node(x);
              insert(head, node);
          }
          void print() {
              print(head);
              cout << endl;
          }
      private:
          Node *head;
          void destroy(Node *&now) {
              if (!now) return;
              cnt++;
              destroy(now->nxt);
              delete now;
              now = NULL;
          }
          void insert(Node *&now, Node *&node) {
              if (now == NULL) {
                  now = node;
                  return;
              }
              insert(now->nxt, node);
          }
          void print(Node *now) {
              if (!now) return;
              cout << now->key << " ";
              print(now->nxt);
          }
      }L;
      
      int main() {
          clock_t rec;
          L.destroy();
          for (int j = 1; j <= 5; j++) {
              rec = clock();
              for (int i = 1; i <= 10000; i++) L.insert(i);
              cout << "time : " << clock() - rec << " ms " ;
              L.destroy();
          }
          return 0;
      }
      

      运行结果如下:

      destroy time : 0 ms
      time : 120 ms destroy time : 383 ms
      time : 506 ms destroy time : 378 ms
      time : 499 ms destroy time : 375 ms
      time : 498 ms destroy time : 375 ms
      time : 507 ms destroy time : 375 ms
      

      仍然是只有第一次运行时时间正常,后面几次时间都长很多。

      且去掉delete之后时间恢复正常。再次确定是delete造成的问题。

    4. 抄了一个网上的红黑树代码,加上delete之后自己跑了一下,还是有这个问题

    5. 建了两颗红黑树,先对第一棵树做一遍插入和清空操作,再对第二棵树做插入操作,发现第二个树的插入时间也变慢了(进一步确定了问题与内存管理的关系)

    重新简述下问题:在清空数据结构时,如果用delete回收了内存,那么会对下一次使用同样数据结构的运行时间产生非常大的影响。但原因未知,希望能找到对于这一现象的解释。

    加了delete之后变慢的时间:

    SIZE :100 RUNTIME : 2 ms
    SIZE :1000 RUNTIME : 2 ms
    SIZE :10000 RUNTIME : 13 ms
    SIZE :100000 RUNTIME : 1049 ms
    SIZE :1000000 RUNTIME : 4881 ms
    

    不加delete正常的运行时间:

    SIZE :100 RUNTIME : 9 ms
    SIZE :1000 RUNTIME : 2 ms
    SIZE :10000 RUNTIME : 8 ms
    SIZE :100000 RUNTIME : 126 ms
    SIZE :1000000 RUNTIME : 1341 ms
    

    (搞了好几天了没搞懂为什么,救救孩子

    附红黑树代码(只有插入操作)

    #include <iostream>
    #include <ctime>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    
    const int MAXN = 1e6 + 5;
    
    int data[MAXN], height;
    
    enum RBTColor{RED, BLACK};
    
    class RBTNode {
    public:
        RBTColor color;
        int key;
        RBTNode *lson;
        RBTNode *rson;
        RBTNode *parent;
        RBTNode(RBTColor c, int k) {
            color = c;
            key = k;
            lson = rson = parent = NULL;
        }
        ~RBTNode() {
            if (lson) delete(lson); lson = NULL;
            if (rson) delete(rson); rson = NULL;
        }
    };
    
    class RBTree {
    public:
        RBTree() {
            root = NULL;
        }
        ~RBTree() {
            destroy();
        }
        void insert(int key) {
            RBTNode *node = new RBTNode(RED, key);
            insert(root, node);
            //cout << "finish" << endl;
        }
        void inOrder() {
            cout << "root : " << root->key << endl;
            inOrder(root);
        }
        void check() {
            check(root, 1);
        }
        void destroy() {
            clock_t rec = clock();
            delete(root);
            root = NULL;
            cout << "destroy time : " << clock() - rec << " ms ";
            // root = NULL;
        }
    private:
        RBTNode *root;
        void check(RBTNode *&x, int h) {
            h += x->color;
            if (x->lson) check(x->lson, h);
            if (x->rson) check(x->rson, h);
            if (x->color == 0) {
                if (x->lson && x->lson->color == 0 || x->rson && x->rson->color == 0)
                    cout << "COLOR ERROR!" << endl;
            }
            if (!x->lson && !x->rson) {
                if (height == 0) height = h;
                else {
                    if (height != h)
                        cout << "HEIGHT ERROR!" << endl;
                }
            }
        }
        void inOrder(RBTNode *&x) {
            if (x->lson) inOrder(x->lson);
            cout << "color : " << (x->color ? "BLACK" : "RED  ");
            cout << " key : " << x->key << endl;
            if (x->rson) inOrder(x->rson);
        }
        void insert(RBTNode *&root, RBTNode *&node) {
            if (root == NULL) {
                root = node; 
                insertFixup(root, root);
                return;
            }
            RBTNode *x = root, *y;
            while(x != NULL) {
                y = x;
                if (node->key < x->key) x = x->lson;
                else x = x->rson;
            }
            x = node;
            x->parent = y;
            if (node->key < y->key) y->lson = node;
            else y->rson = node;
            insertFixup(root, node);
        }
        void leftRotate(RBTNode *&root, RBTNode *&x) {
            RBTNode *y = x->rson, *z = x->parent;
            if (z == NULL) root = y;
            else 
                if (z->lson == x) z->lson = y;
                else z->rson = y;
            y->parent = x->parent;
            x->parent = y;
            x->rson = y->lson;
            if (x->rson) {
                x->rson->parent = x;
            }
            y->lson = x;
        }
        void rightRotate(RBTNode *&root, RBTNode *&x) {
            RBTNode *y = x->lson, *z = x->parent;
            if (z == NULL) root = y;
            else
                if (z->lson == x) z->lson = y;
                else z->rson = y;
            y->parent = x->parent;
            x->parent = y;
            x->lson = y->rson;
            if (x->lson) {
                x->lson->parent = x;
            }
            y->rson = x;
        }
        void insertFixup(RBTNode *&root, RBTNode *&x) {
            if (root == x) {
                x->color = BLACK;
                return;
            }
            RBTNode *y = x->parent;
            if (y->color == RED) {
                RBTNode *gparent = y->parent;
                if (gparent->lson == y) {
                    RBTNode *uncle = gparent->rson;
                    if (uncle && uncle->color == RED) {
                        uncle->color = y->color = BLACK;
                        gparent->color = RED;
                        insertFixup(root, gparent);    
                    } else {
                        if (y->rson == x) {
                            leftRotate(root, y);
                            swap(x, y);
                        }
                        gparent->color = RED;
                        y->color = BLACK;
                        rightRotate(root, gparent);
                    }
                } else {
                    RBTNode *uncle = gparent->lson;
                    if (uncle && uncle->color == RED) {
                        uncle->color = y->color = BLACK;
                        gparent->color = RED;
                        insertFixup(root, gparent);
                    } else {
                        if (y->lson == x) {
                            rightRotate(root, y);
                            swap(x, y);
                        }
                        gparent->color = RED;
                        y->color = BLACK;
                        leftRotate(root, gparent);
                    }
                }
            }    
        }
        void destroy(RBTNode *&root) {
            if (root == NULL) return ;
            if (root->lson) destroy(root->lson);
            if (root->rson) destroy(root->rson);
            delete root;
            root = NULL;
        }
    }rb_tree;
    
    class randInt {
    public:
        randInt(int n, int s, int t):_n(n), _s(s), _t(t) {
            _r = _t - _s + 1;
            get = 0;
            exi = new bool[_r];
            number = new int[n];
            memset(exi, 0, sizeof(bool) * _r);
            memset(number, 0, sizeof(int) * _n);
        }
        ~randInt() {
            delete[] exi;
            delete[] number;
        }
        void generate_no_duplicate() {
            for (int i = 0; i < _n; i++) {
                int res = rand() * rand() % _r + _s;
                while(exi[res - _s]) res = rand() * rand() % _r + _s;
                exi[res - _s] = 1;
                number[i] = res;
            }
        }
        int getNum() {
            return number[get++];
        }
    private:
        int _n, _s, _t, _r, get;
        bool *exi;
        int *number;
    };
    
    void calc_time(int SIZE, int s, int t) {
        rb_tree.destroy();
        clock_t rec = clock();
        for (int i = 0; i < SIZE; i++) {
            rb_tree.insert(data[i]);
        }
        cout << "SIZE : " << SIZE << " RUNTIME : " << clock() - rec << " ms" << endl;
    }
    
    int main() {
        srand(time(NULL));
        int n, s, t; 
        for (int i = 0; i < MAXN; i++) data[i] = i;
        random_shuffle(data, data + MAXN);
        for (int i = 1; i <= 5; i++) {
            calc_time(1000000, s, t);
        }
        return 0;
    }
    
    展开全文
  • cocos-lua 中的require占用内存影响 require会使得被引用的对象,执行初始化动作,即onCreate,但是不会onEnter 本意是为了在使用时免去临时创建的时间,增加流畅度。但是长久的不使用也不清空,会一直占用内存,...
  • 之前在水木上看到过讨论一段代码到底是哪些操作会较大影响程序时间,记得主要是内存的申请及memset,个人准备研究下为什么会产生影响,以及有无优化的方法。   后续待补。   参考 malloc()之后,...
  • 内存分配对性能的影响是很大的,分配内存本身需要时间,垃圾回收器回收内存也需要时间,所以应该尽量避免在堆里分配内存。不过直到最近优化HoLa cantk时,我才深刻的体会到内存分配对性能的影响,其中有一个关于...
  • 内存时序由4个数字组成,中间用破折号隔开,例如16-18-18-38这些数字表示延迟,也就是内存的反应时间。当内存接收到CPU发来的指令后,通常需要几个时钟周期来处理它,比如访问某一块数据。所以,时间越短,内存性能...
  • 2-2-2-8 4个数字的含义依次为:CAS Latency(简称CL值)内存CAS延迟时间,他是内存的重要参数之一,某些牌子的内存会把CL值印在内存条的标签上。RAS-to-CAS Delay(tRCD),内存行地址传输到列地址的延迟时间。Row...
  • 内存的大小,对编译时间有什么影响?这两天对这两个方面进行了测试。 结论: 1、现有大部分Mac配置了i7处理器,应设置并发任务数量为8,可以达到最佳效果 2、4G内存及8G内存下,编译时间是基本一样的,故...
  • 点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!...什么是服务器并发处理能力一台服务器在单位时间里能处理的请求越多,服务器的能力越高,也就是服务器并发处理能力越强有什么方法衡量服务器并...
  • 最近一时感兴趣,想要测试一下GeoServer的并发性能,毕竟...增大GeoServer运行内存,对于1000以上并发量,会提升影响速度,尤其在测试中对10000作用十分明显,512M时响应时间为69s,1024M为34秒,响应时间直接降为50%
  • websocket影响内存泄漏的两个点

    万次阅读 2018-03-25 14:57:53
    前段时间一直遇到websocket的内存溢出问题,最后在排除了代码的问题之后,开始查找了框架的问题,最后找到了两个框架会影响到的坑,mark一下,顺便分享给大家首先说项目:springboot的内置tomcat启动,用的websocket...
  •  1、 如果网速低也有影响,换个时间吧。  2、 硬件配置不足,内存较小、CPU较差,建议升级电脑。内存条起码要2G。  内存条是连接CPU 和其他设备的通道,起到缓冲和数据交换作用。当CPU在工作时,需要从硬盘等...
  • 大家好啊,因为工作原因,实在没有时间更新,但是我尽量保证每天更新一篇科普,总之,谢谢大家的观看,还有提点就是,别在我评论区下面卖电脑还有吵架,谢谢! 今天呢为大家继续讲解内存条的知识,那么上一篇文章...
  • 1. 尽量在合适的场合使用单例使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:第一,控制资源的使用,通过线程同步来控制资源...
  • 目前所有的回答都是基于过去DDR4、DDR3、甚至DDR2的普及历史,做出的评估。...变革1:疫情影响显然明年整年,世界还将在疫情中艰难前行。疫情大大削弱了非工作生活必需品的销量,体现在芯片上,就是手机芯片疲弱,而...
  • 存内的巨细,对译编间时有什么影响?这两天对这两个方面行进了测试。 每日一道理 哦,妈妈 亲爱的妈妈,您对我的爱比太阳还要炽热,比白雪更为圣洁。在我成长的道路上,您就是女儿夏日里的浓荫,冬天里的炭火,您...
  • 空指针的使用可能造成错误,指针初始化的时候未赋初值而造成的野指针的... 程序的具体问题如下,在处理比较小的图片的时候,直接运行会发生错误,原因是内存访问越界(提示为该内存不能read)。但是用F5调试运行的时候
  • 消耗时间:线程的创建和销毁都需要时间,当有大量的线程创建和销毁时,那么这些时间的消耗则比较明显,将导致性能上的缺失非常耗CPU和内存:大量的线程创建、执行和销毁是非常耗cpu和内存的,这样将直接影响系统的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,697
精华内容 1,878
关键字:

内存影响时间