zoukankan      html  css  js  c++  java
  • GDAL RasterIO 速度测试程序

    简述

    这是很早期的时候写的一个小工具,用来给非开发人员对不同的存储环境进行 GDALRasterIO 的速度进行测试。
    最近翻出了这个程序,升级到了 QT 5.15 版本,开源出来供有同样需要的朋友参考吧。

    这个工具的原理很简单,就是分别按照 256x256512x5121024x1024 读取影像的像素数据,读取的时候不会刚刚好从 0,0 坐标开始读,会有一个随机偏移值,以便不会恰好按照影像的分块大小进行读取。

    关键代码

    关键代码部分如下:

    const int updateblock = 50;
    void GDALRasterIOSpeedWorker::doGDALRasterIOSpeedTest(QString path)
    {
        QString msg;
        int     allblockcount = 0;
    
        GDALDatasetH hDset = GDALOpen(toU8String(path).c_str(), GA_ReadOnly);
        if (hDset == NULL) {
            msg = QString::fromUtf8(CPLGetLastErrorMsg());
            emit doGDALRasterIOSpeedTestMsg(msg);
            emit doGDALRasterIOSpeedTestFinished();
            return;
        }
        std::unique_ptr<void, void (*)(GDALDatasetH)> dsetptr(hDset, GDALClose);
    
        msg = path + QStringLiteral("  影像打开成功");
        emit doGDALRasterIOSpeedTestMsg(msg);
    
        int nBands = GDALGetRasterCount(hDset);
        msg        = QStringLiteral("影像波段数为: ") + QString::number(nBands);
        emit doGDALRasterIOSpeedTestMsg(msg);
    
        if (nBands < 1) {
            msg = QStringLiteral("没有可用影像波段");
            emit doGDALRasterIOSpeedTestMsg(msg);
            emit doGDALRasterIOSpeedTestFinished();
            return;
        }
        if (nBands > 16) { nBands = 16; }
    
        GDALRasterBandH hBand = GDALGetRasterBand(hDset, 1);
    
        int width = GDALGetRasterBandXSize(hBand);
        int hight = GDALGetRasterBandYSize(hBand);
        int nXSzie, nYSize;
        GDALGetBlockSize(hBand, &nXSzie, &nYSize);
    
        GDALDataType datatype = GDALGetRasterDataType(hBand);
    
        msg = QStringLiteral("影像大小: ") + QString::number(width) + QString('X') +
              QString::number(hight) + QStringLiteral("      存储分块大小: ") +
              QString::number(nXSzie) + QString('X') + QString::number(nYSize) +
              QStringLiteral("      数据类型: ") + GDALGetDataTypeName(datatype);
        emit doGDALRasterIOSpeedTestMsg(msg);
    
        if (width < 4096 || hight < 4096) {
            msg = QStringLiteral("图像太小,不支持小图测试");
            emit doGDALRasterIOSpeedTestMsg(msg);
            emit doGDALRasterIOSpeedTestFinished();
            return;
        }
        if (width > 20480) { width = 20480; }
        if (hight > 20480) { hight = 20480; }
    
        msg = QStringLiteral("开始测速");
        emit doGDALRasterIOSpeedTestMsg(msg);
    
        std::vector<uint64_t> buffer((size_t)(1024 * 1024 * nBands), 0);
    
    
        std::function<void(QString, int, int&, int&, int)> func =
            [nBands, width, hight, datatype, buffer, this](
                QString Path, int blocksize, int& blockcount, int& allblockcount, int mode) {
                std::vector<std::pair<int, int>> xy0;
    
                // mode 0:行优先读取;  1:列优先;  2随机
                if (mode == 0) {
                    // 读取起点的初始值设置在 16~31 之间的随机数
                    for (int y = 16 + (rand() % 16); y < hight; y += blocksize) {
                        for (int x = 16 + (rand() % 16); x < width; x += blocksize) {
                            xy0.push_back(std::make_pair(x, y));
                        }
                    }
                }
                else {
                    for (int x = 16 + (rand() % 16); x < width; x += blocksize) {
                        for (int y = 16 + (rand() % 16); y < hight; y += blocksize) {
                            xy0.push_back(std::make_pair(x, y));
                        }
                    }
                }
                if (mode == 2) { std::random_shuffle(xy0.begin(), xy0.end()); }
    
                for (const auto& xy : xy0) {
                    int x  = xy.first;
                    int y  = xy.second;
                    int rw = (width - x) > blocksize ? blocksize : (width - x);
                    int rh = (hight - y) > blocksize ? blocksize : (hight - y);
    
                    GDALDatasetH hDset = GDALOpen(toU8String(Path).c_str(), GA_ReadOnly);
                    if (hDset == NULL) { continue; }
    
                    CPLErr err = GDALDatasetRasterIO(hDset, GF_Read, x, y, rw, rh,
                                                     (void*)buffer.data(), rw, rh, datatype,
                                                     nBands, NULL, 0, 0, 0);
                    if (err == CPLE_None) { ++blockcount; }
                    ++allblockcount;
                    if (allblockcount % updateblock == 1) {
                        emit this->doGDALRasterIOSpeedTestBlockNumber(allblockcount);
                    }
                    GDALClose(hDset);
                }
            };
    
    
        auto runTestFunc = [this, path, func](
                               QString title, int mode, int blocksize, int& allblockcount) {
            int           blockcount = 0;
            QElapsedTimer et;
            et.start();
            func(path, blocksize, blockcount, allblockcount, mode);
            qint64 elapsed = et.elapsed();
    
            QString msg = title + QStringLiteral(" 读取总块数:") + QString::number(blockcount) +
                          QStringLiteral("  读取总耗时:") + QString::number(elapsed) +
                          QStringLiteral("毫秒
    ") + QStringLiteral("平均每块耗时:") +
                          QString::number(double(elapsed) / blockcount) + QStringLiteral("毫秒
    ");
            emit doGDALRasterIOSpeedTestMsg(msg);
        };
    
        runTestFunc(QStringLiteral("256分块(行优先)"), 0, 256, allblockcount);
        runTestFunc(QStringLiteral("256分块(列优先)"), 1, 256, allblockcount);
        runTestFunc(QStringLiteral("256分块(随机序)"), 2, 256, allblockcount);
    
        runTestFunc(QStringLiteral("512分块(行优先)"), 0, 512, allblockcount);
        runTestFunc(QStringLiteral("512分块(列优先)"), 1, 512, allblockcount);
        runTestFunc(QStringLiteral("512分块(随机序)"), 2, 512, allblockcount);
    
        runTestFunc(QStringLiteral("1024分块(行优先)"), 0, 1024, allblockcount);
        runTestFunc(QStringLiteral("1024分块(列优先)"), 1, 1024, allblockcount);
        runTestFunc(QStringLiteral("1024分块(随机序)"), 2, 1024, allblockcount);
    
    
        emit doGDALRasterIOSpeedTestFinished();
        return;
    }
    

    项目git仓库

    仓库地址: https://gitee.com/solym/GDALRasterIOSpeed.git

  • 相关阅读:
    《信息安全专业导论》第十周学习总结
    《信息安全专业导论》第九周学习总结
    《信息安全导论》第八周学习总结
    《信息安全专业导论》第七周学习总结
    《信息安全专业导论》第六周学习总结
    《信息安全专业导论》第五周学习总结
    《信息安全专业导论》第四周学习总结
    《信息安全专业导论》第三周学习总结
    信息安全导论第二周学习总结
    计算机概论速读时的问题
  • 原文地址:https://www.cnblogs.com/oloroso/p/14777901.html
Copyright © 2011-2022 走看看