在处理遥感图像中,发现往往比较耗时的是在数据的IO中,尤其是在O(写入)的时候更加耗时。GDAL可以支持图像的多线程写入,下面结合实例进行简单的测试,看看实际效果会不会提高。

在这里我使用的是boost库的thread库来进行多线程创建。下面先使用计算PI来对boost的thread有个简单的说明。这里的计时使用的是boost的progress_timer。下面是使用多线程计算PI的一段小代码,对于多线程计算的10部分没有加起来。

#include <stdio.h>
#include <boost/progress.hpp> //boost计时函数
#include <boost/thread.hpp>       //boost多线程
#include <boost/bind.hpp>     //boost bind库
using namespace boost;//计算PI的个数
int iSize = 1000000000;
int iSize1 = 100000000;//使用普通方式计算
double CalcPi_S()
{double dPi = 0.0;int iFlag = 1;for (int k=0; k<=iSize; k++){dPi = dPi + iFlag/(2*k+1.0);iFlag = -iFlag;}return dPi*4;
}//多线程计算核心函数
void ThreadPi(int iStart, int iEnd)
{double dPi = 0.0;int iFlag = 1;for (int k=iStart; k<=iEnd; k++){dPi = dPi + iFlag/(2*k+1.0);iFlag = -iFlag;}printf("%18.16lf\n", dPi*4);
}//多线程计算函数
void CalcPi_M()
{for (int i=0; i<10; i++){boost::thread thrd(boost::bind(&ThreadPi, i*iSize1, (i+1)*iSize1));thrd.join();}
}int main()
{//不使用多线程处理progress_timer *pTime = new progress_timer();  // 开始计时printf("单线程计算PI\n");double dsPi = CalcPi_S();printf("计算结束,耗时:%f PI=%18.16lf\n", pTime->elapsed(), dsPi);//使用多线程处理pTime->restart(); // 开始计时printf("多线程计算PI\n");CalcPi_M();printf("计算结束,耗时:%f\n", pTime->elapsed());delete pTime;system("pause");return 0;
}

通过对上面的代码进行测试,使用的是Release编译的结果,结果大概如下,第一次:

单线程计算PI
计算结束,耗时:9.643000 PI=3.1415926545880506
9.64 s多线程计算PI
3.1415926635893259
0.0000000150000000
0.0000000083333333
0.0000000058333333
0.0000000045000000
0.0000000036666667
0.0000000030952381
0.0000000026785714
0.0000000023611111
0.0000000021111111
计算结束,耗时:8.498000
8.50 s请按任意键继续. . .

第二次:

单线程计算PI
计算结束,耗时:12.039000 PI=3.1415926545880506
多线程计算PI
3.1415926635893259
0.0000000150000000
0.0000000083333333
0.0000000058333333
0.0000000045000000
0.0000000036666667
0.0000000030952381
0.0000000026785714
0.0000000023611111
0.0000000021111111
计算结束,耗时:8.550000
8.55 s请按任意键继续. . .

第三次:

单线程计算PI
计算结束,耗时:14.473000 PI=3.1415926545880506
多线程计算PI
3.1415926635893259
0.0000000150000000
0.0000000083333333
0.0000000058333333
0.0000000045000000
0.0000000036666667
0.0000000030952381
0.0000000026785714
0.0000000023611111
0.0000000021111111
计算结束,耗时:8.500000
8.50 s请按任意键继续. . .

第四次:

单线程计算PI
计算结束,耗时:10.898000 PI=3.1415926545880506
多线程计算PI
3.1415926635893259
0.0000000150000000
0.0000000083333333
0.0000000058333333
0.0000000045000000
0.0000000036666667
0.0000000030952381
0.0000000026785714
0.0000000023611111
0.0000000021111111
计算结束,耗时:8.510000
8.51 s请按任意键继续. . .

通过四次测试,发现多线程还是能够稍微提高点速度,但是不知道为什么,单线程计算的时候,时间跳跃比较大,起伏较大,不知道是什么原因,有知道的童鞋望不吝告知。

下面是创建了一个10000×10000的单波段图像,格式是Erdas的img格式,图像的内容是按照行号对255取余的结果,结果图像就是一条一条的黑白相间的波纹。多线程还是使用10个线程来写图像的不同部分。代码如下:

#include <stdio.h>
#include "gdal_priv.h"#include <boost/progress.hpp> //boost计时函数
#include <boost/thread.hpp>
#include <boost/bind.hpp>
using namespace boost;#pragma comment(lib, "gdal_i.lib")typedef unsigned char DT_8U;/**
* @brief 创建输出图像
*/
bool CreateImage(const char* pszFile)
{GDALAllRegister();GDALDriverH hDriver = GDALGetDriverByName( "HFA" );if( hDriver == NULL )return false;GDALDatasetH hDstDS = GDALCreate( hDriver, pszFile, 10000, 10000, 1, GDT_Byte, NULL );    //创建输出文件if( hDstDS == NULL )return false;GDALClose(hDstDS);return true;
}bool SingleProcess(const char* pszFile)
{GDALAllRegister();GDALDataset *poSrcDS = (GDALDataset *) GDALOpen( pszFile, GA_Update );if( poSrcDS == NULL )return false;int iWidth = poSrcDS->GetRasterXSize();int iHeight = poSrcDS->GetRasterYSize();GDALRasterBand *pBand = poSrcDS->GetRasterBand(1);DT_8U *pBuf = new DT_8U[iWidth];memset(pBuf, 0, sizeof(DT_8U)*iWidth);  //超出AOI外for (int i=0; i<iHeight; i++){int iValue = i % 255;memset(pBuf, iValue, sizeof(DT_8U)*iWidth);   //超出AOI外pBand->RasterIO(GF_Write , 0, i, iWidth, 1, pBuf, iWidth, 1, GDT_Byte, 0, 0);}GDALClose((GDALDatasetH) poSrcDS);return true;
}void ThreadFun(const char* pszFile, int iStart, int iEnd/*, int index*/)
{GDALAllRegister();GDALDataset *poSrcDS = (GDALDataset *) GDALOpen( pszFile, GA_Update );if( poSrcDS == NULL )return;int iWidth = poSrcDS->GetRasterXSize();int iHeight = poSrcDS->GetRasterYSize();GDALRasterBand *pBand = poSrcDS->GetRasterBand(1);DT_8U *pBuf = new DT_8U[iWidth];memset(pBuf, 0, sizeof(DT_8U)*iWidth);    //超出AOI外for (int i=iStart; i<iEnd; i++){int iValue = i % 255;memset(pBuf, iValue, sizeof(DT_8U)*iWidth); //超出AOI外pBand->RasterIO(GF_Write , 0, i, iWidth, 1, pBuf, iWidth, 1, GDT_Byte, 0, 0);}GDALClose((GDALDatasetH) poSrcDS);//printf("线程%n结束\n", index);
}bool MultiProcess(const char* pszFile)
{for (int i=0; i<10; i++){boost::thread thrd(boost::bind(&ThreadFun, pszFile, i*1000, (i+1)*1000/*, i*/));thrd.join();}return true;
}int main()
{//不使用多线程处理progress_timer *pTime = new progress_timer();  // 开始计时const char* pszFileSingle = "F:\\Data\\Test\\Single.img";printf("创建图像开始\n");CreateImage(pszFileSingle);printf("创建图像结束,耗时:%f\n", pTime->elapsed());pTime->restart(); // 开始计时SingleProcess(pszFileSingle);printf("单线程处理图像结束,耗时:%f\n", pTime->elapsed());//使用多线程处理pTime->restart(); // 开始计时const char* pszFileMulti = "F:\\Data\\Test\\Multi.img";printf("创建图像开始\n");CreateImage(pszFileMulti);printf("创建图像结束,耗时:%f\n", pTime->elapsed());pTime->restart(); // 开始计时MultiProcess(pszFileMulti);printf("多线程处理图像结束,耗时:%f\n", pTime->elapsed());delete pTime;system("pause");return 0;
}

依旧使用Release编译的结果,运行的结果如下,第一次:

创建图像开始
创建图像结束,耗时:2.852000
单线程处理图像结束,耗时:20.579000
创建图像开始
创建图像结束,耗时:3.261000
多线程处理图像结束,耗时:29.343000
29.34 s请按任意键继续. . .

第二次:

创建图像开始
创建图像结束,耗时:2.034000
单线程处理图像结束,耗时:22.311000
创建图像开始
创建图像结束,耗时:2.217000
多线程处理图像结束,耗时:30.570000
30.57 s请按任意键继续. . .

第三次:

创建图像开始
创建图像结束,耗时:2.007000
单线程处理图像结束,耗时:20.285000
创建图像开始
创建图像结束,耗时:2.267000
多线程处理图像结束,耗时:28.723000
28.73 s请按任意键继续. . .

就贴三次吧,在我电脑上测试了不下十次,发现都是多线程写入的速度慢,但是结果图像是对的。对于出现这种情况,也是出乎意料的,按理说多线程应该更快才对,但是这里却出现了相反的情况,不知道是不是boost库多线程的问题还是多线程写入图像的问题,不管是什么情况,对于想使用多线程来创建图像的人来说,这条路可能比想象中的要更加艰难。

如果你有更好的方式,望告知,谢谢。

多线程写图像文件的一点小测试相关推荐

  1. 用c语言写心理测试,心理小测试题目及答案

    心理小测试题目及答案 心理测试是一种比较先进的测试方法,它是指通过一系列手段,将人的某些心理特征数量化,来衡量个体心理因素水平和个体心理差异差异的一种科学测量方法.下面是小编整理的心理小测试题目及答案 ...

  2. 作为面试官的一点小感想

    这两天公司要招大数据开发的人,让我去面试这些应聘者,几天下来面试的人也有10多个人了,这其中有应届生.刚工作不久的以及有一定年限的,学历有本科和研究生等.通过和这些人交谈后,心里也有一点小感触和小想法 ...

  3. 手写数字识别的小优化

    在用KNN实现手写数字识别的时候突发奇想是否可以根据数字的特点对其进行一个分类,以此来提高判断的准确率.经过许多天的改进与完善终于实现了此算法,就称其为洞拐法吧.(第一次写,有许多不足之处,还望多多包 ...

  4. 硬核,学习 Java 的一点小建议(思维导图,建议收藏)!

    CSDN 收到一条读者的私信,情真意切,所以我承诺他今天一定写篇文章好好回复他一下.先来看一下他的私信内容吧. 首先映入我的眼帘的是这个称呼--"老前辈",我一下子没忍住,笑了! ...

  5. jupyter中怎么把图形在一个单独的窗口显示_【一点小套路】手把手从安装Python到完成第一个数据分析项目...

    上一期的[一点小套路]只是讲了方法论,而没有真正意义上做到一份step by step的教程.所以,尼同学决定,这就给各位零基础的同学做一期手把手教学.全文将会从安装→Jupyter基础→数据分析与建 ...

  6. 写出你所知道的测试工具,并写出他们的用途和优缺点

    写出你所知道的测试工具,并写出他们的用途和优缺点: Jmeter   Apache JMeter是Apache组织开发的基于Java的压力测试工具.   Apache jmeter 可以用于对静态的和 ...

  7. 一行代码不用写,就可以训练、测试、使用模型,这个 star 量 1.5k 的项目帮你做到...

    公众号关注 "小詹学Python" 设为"星标",第一时间知晓最新干货~ 转自 | 机器之心 igel 是 GitHub 上的一个热门工具,基于 scikit- ...

  8. 你写的代码一点都不 Pythonic

    可能有时候你在论坛上 会看到有人这样说 "你写的代码 一点都不 Pythonic" what? Pythonic? 什么是 Pythonic 呢 其实说白了就是你的 代码风格 有些 ...

  9. 函数的傅立叶展开掐死我吧_关于文章《傅里叶分析之掐死教程》的再一点小思考...

    封火星:关于文章<傅里叶分析之掐死教程>的一点小思考​zhuanlan.zhihu.com 以前的文章,从原理上更好的理解了原文中的一点,不过因为公式不是完全一样,从而有一个新问题不能解决 ...

最新文章

  1. mysql导出数据 程序_MySQL数据导出与导入程序代码
  2. Java学习笔记50:JSONObject与JSONArray的使用
  3. Android高级开发专题晋升班
  4. windows 禁用ipv6服务_在 Windows 7 中禁用IPv6协议/IPv6隧道
  5. proe2001安装指南
  6. java mysql blob 存储图片_Java操作mysql存储图片
  7. 会议系统m900服务器网口灯,【中兴视频会议多点控制单元ZXV10 M900-64MA 今日特卖】价格,厂家,视讯会议系统-搜了网...
  8. wpf listview 切换数据源 位置不刷新_连载| 8 初识数据源
  9. 华为Mate50渲染图曝光:经典奥利奥相机模组
  10. ionic3 创建和启动
  11. 监听listview item兼容于checkbox/textview/imageview
  12. Illegal use of when-style tag without ...
  13. Win10 安装 .NetFramework 4.7 (SourceTree)
  14. CMS采集插件-CMS自动采集插件免费
  15. Android安全测试
  16. Python-自学爬虫篇
  17. OpenCV算法加速的一些学习总结
  18. java界面——可视化窗口入门级
  19. 产品分析——外研随身学
  20. redhat6.5进入救援

热门文章

  1. 孤岛生存java_我的世界:一座孤岛等于拥有“全部”,这个孤岛种子非常适合生存...
  2. 移动机器人场景应用对比分析
  3. 快速生成HTML结构语法(HTML、CSS)
  4. Angular 项目打包之后,部署到服务器,刷新访问404解决方法
  5. 计算机html二级难度,计算机二级考试越来越难的实锤!真实数据告诉你到底难在哪里?...
  6. 电脑管家pc版离线包_王国统治电脑版下载_王国统治游戏pc版下载[策略经营]
  7. 关于playframework1.2.4 static 关键字使用的一些思考
  8. Oracle推断值为非数字
  9. 【李宏毅2020 ML/DL】P79 Generative Adversarial Network | Tips for improving GAN
  10. 《强化学习》中的时序差分控制:Sarsa、Q-learning、期望Sarsa、双Q学习 etc.