zoukankan      html  css  js  c++  java
  • GDAL读取影像测试速度程序

    这个程序代码是很多年前一个同事写的,之前我们写过很多这样零碎测试的代码,时间太久了,很多都遗忘了。现在放这里做一个备份,也供需要的人做个参考。

    程序使用说明

    模式1
      分配任务方式:
    	将所有图片依次依序分配读取任务,每次任务读取的数据量由buff能容纳的量决定
    	现在默认为500MB,可以修改main.cpp的参数如下来调整
    	#define MAXBUFSIZE  (1024 * 1024 * 500)   	//500M
      是否支持随机读取:
    	支持,通过--random 参数指定
    
    
    模式2
      分配任务方式:
    	将所有图片依次依序分配读取任务,每次任务读取512*512,buff也是512*512,没有抽析过程。
      是否支持随机读取:
    	支持,通过--random 参数指定
    
    
    模式3
      分配任务方式:
    	将所有图片依次依序分配读取任务,每次任务进行抽析,buff是512*512,逐层级进行抽析。
      是否支持随机读取:
    	支持,通过--random 参数指定
    

    程序代码

    /***************************************************************************
    * Project:  gdalread
    * Purpose:  Implement gdal read speed test.
    * Author:   Chengsong of ... COMPANY
    ****************************************************************************
    * Copyright (c)
    ****************************************************************************/
    
    #ifdef WIN32
    #	include <windows.h>
    #	include "gdal_priv.h"
    #	include <io.h>	
    #else 
    #	include <sys/time.h>
    #	include <unistd.h>
    #	include "./include/gdal_priv.h"
    #	include <stdio.h>  
    #	include <string.h> 
    #	include <stdlib.h>  
    #	include <dirent.h>  
    #	include <sys/stat.h>  
    #	include <unistd.h>  
    #	include <sys/types.h> 
    #	include <iostream>
    #endif
    
    #include "getopt.h"
    #include <iostream>
    #include <mutex>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <string>
    #include <fstream> 
    
    using std::string;
    using std::cout;
    using std::endl;
    using std::ifstream;
    using std::vector;
    using std::string;
    using std::cout;
    using std::hex;
    using std::endl;
    using std::setw;
    using std::streambuf;
    using std::ofstream;
    using std::setiosflags;
    using std::setprecision;
    using std::ios;
    using std::mutex;
    
    #ifndef no_argument
    #	define	no_argument			0
    #endif
    #ifndef required_argument
    #	define required_argument	1
    #endif
    #ifndef opt_argument
    #	define opt_argument	2
    #endif
    
    const struct option longOpts[] = {
    	{ "help", no_argument, NULL, 'h' },
    	{ "recursive", no_argument, NULL, 'r' },
    	{ "nodetail", no_argument, NULL, 'n' },
    	{ "verbose", no_argument, NULL, 'v' },
    	{ "path", required_argument, NULL, 'p' },
    	{ "mode", required_argument, NULL, 'm' },
    	{ "deap", required_argument, NULL, 'd' },
    	{ "layer", required_argument, NULL, 'l' },
    	{ "out", required_argument, NULL, 'o' },
    	{ "ext", required_argument, NULL, 'e' },
    	{ "thread", required_argument, NULL, 't' },
    	{ "random", no_argument, NULL, 1 },
    	{ NULL, 0, NULL, 0 },
    };
    static const char *optString = "hrnvp:m:d:o:l:e:t:";
    
    string oPath;
    string oMode;
    string oOutFile;
    string oFileExt;
    int    mode;
    char   timE[80];
    #define SPLITLINE "  --------------------------------------------------------------------------------------------------------------------------------------------"
    #define MAXBUFSIZE  (1024 * 1024 * 500)   	//500M
    
    GUIntBig TotalFilesSize;
    int threads;
    int deapth;
    bool recursive;
    bool nodetail;
    bool verbose;
    bool bContinue;
    bool bRandom;
    int bound_map[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int setedlayer;
    int curlayer = 1;
    #define MAXTHREADNUM 300
    int ThreadRetFlag[MAXTHREADNUM];
    int ThreadRetFlagPos;
    ofstream of;
    streambuf* coutBuf;
    streambuf* fileBuf;
    
    #define MAXBANDNUM 10
    #define MAXBANDDEAP 3
    #define MALLOC521BLOCKSIZE (512*512*MAXBANDNUM*MAXBANDDEAP)
    GByte * pblock512buff[MAXTHREADNUM];
    
    vector<string> files;
    int file_num;
    const char* pszLocalPath;
    
    typedef struct{
    	const char* filepath;
    	int START_X;
    	int START_Y;
    	int SIZE_X;
    	int SIZE_Y;
    	int SIZE_OUT_X;
    	int SIZE_OUT_Y;
    	int bands;
    	int deap;
    	int rand;
    	int f_sizex;
    	int f_sizey;
    }TASK;
    
    typedef vector<TASK> TASKGROUP;
    typedef vector<TASKGROUP> ALLTASK;
    ALLTASK AllTask;
    int taskg_num = 0;
    
    typedef struct{
    	const char* filepath;
    	GUIntBig SIZE;	//MB
    	int SIZE_X;
    	int SIZE_Y;
    	int bands;
    	int deap;
    }info;
    typedef vector<info> FILESINFO;
    FILESINFO FilesInfo;
    
    CPLString str_print;
    int str_print_pos;
    
    //Function Declaration
    int  GDALReadFile(const char* pszLocalFilePath, int extend);
    void FormatPrint(const char* pszLocalFile, GIntBig  nFileSize, int nSizeX, int nSizeY, int Bands, int deap, long timeuse_ms);
    void f_ExitIfTure(int val, const char* pstr);
    void getFiles(string path, vector<string>& files);
    void helpinfo(void);
    char* DateTimeStr(void);
    void GatherFilesInfo(void);
    void AssignTask_mode1(void);
    void AssignTask_mode2(void);
    int AssignTask_mode3(int count);
    void StartThread(void);
    void WaitUntilFinished(void);
    void PerformThread(void* parg);
    void TaskOutput(TASK* task, float timeuse_ms, CPLString & osOut, GIntBig PID);
    void TaskGroupOutput(TASKGROUP* taskg, float timeuse_ms, CPLString & osOut, GIntBig PID);
    
    /************************************************************************/
    /*                              helpinfo()                              */
    /************************************************************************/
    void helpinfo(void)
    {
    #ifdef WIN32
    	cout << "说明:
    "
    		<< "  -p or --path          指定文件夹。
    "
    		<< "  -r or recursive [opt] 指定是否递归搜索子文件夹内的文件,不指定,则不递归搜索。
    "
    		<< "  -m or --mode          指定读取模式,现有三种模式:1 2 3。
    "
    		<< "  -t or --thread  [opt] 指定并发线程数量,不指定,则为单线程。
    "
    		<< "  -d or --deap    [opt] 指定读取层级深度。不指定,则读取所有有效层级深度,直到放大一次。
    "
    		<< "  -l or --layer   [opt] 指定读取层级。
    "
    		<< "  -v or --verbose [opt] 指定输出详细信息。,不指定,则不输出详细信息。
    "
    		<< "  -n or nodetail  [opt] 仅输出总结信息。
    "
    		<< "  -o or --out     [opt] 指定输出文件名,不指定,则以时间为文件名。
    "
    		<< "  -e or --ext     [opt] 指定图片数据的后缀名,默认为tif,不需要输入 "."。
    "
    		<< "  --random        [opt] 实现随机读取,不指定则为顺序读。
    "
    		<< "示例:
    ";
    #else
    	cout << "Description:
    "
    		<< "  -p or --path          Specified the path.
    "
    		<< "  -r or recursive [opt] Recursive search for files within a sub folder.
    "
    		<< "  -m or --mode          Specifies the reading mode, there are three modes: 1 2 3.
    "
    		<< "  -t or --thread  [opt] thread number, the maximum is 300.
    "
    		<< "  -d or --deap    [opt] Set the depth of reading layer by layer.
    "
    		<< "  -l or --layer   [opt] Set the specified layer.
    "
    		<< "  -v or --verbose [opt] Output details
    "
    		<< "  -n or nodetail  [opt] Only output summary information
    "
    		<< "  -o or --out     [opt] Specify the output file name.If you do not specify a file
    "
    		<< "  -e or --ext     [opt] specifies the file extension (default is TIF), do not need to add ".".
    "
    		<< "  --random        [opt] Implementation of random read.
    "
    		<< "Examples:
    ";
    #endif
    	cout << "  gdalread -p D:\test -m 1 
    "
    		<< "  gdalread -p D:\test -m 1 -o out1.txt -e jpg 
    "
    		<< "  gdalread -p D:\test -m 2 
    "
    		<< "  gdalread -p D:\test -m 3 
    "
    		<< "  gdalread -p D:\test -m 3 -t 4 
    "
    		<< "  gdalread -p D:\test -m 3 -t 4 -d 4 
    "
    		<< "  gdalread -p D:\test -m 3 -t 4 -l 4 
    ";
    	exit(0);
    }
    
    /************************************************************************/
    /*                                main()                                */
    /************************************************************************/
    
    int compare(const TASKGROUP &a, const TASKGROUP &b)
    {
    	return a.at(0).rand > b.at(0).rand;
    }
    
    #include <algorithm>
    int main(int argc, char ** argv)
    {
    	GDALAllRegister();
    	int bHaveUnknownPara = 0;
    	int opt = 0;
    	int longIndex = 0;
    
    	if (argc == 1)
    		helpinfo();
    
    	opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
    
    	while (opt != -1)
    	{
    		switch (opt)
    		{
    		case 'p':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			oPath = optarg;
    			break;
    		case 'm':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			oMode = optarg;
    			break;
    		case 'd':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			deapth = atoi(optarg);
    			break;
    		case 'l':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			setedlayer = atoi(optarg);
    			break;
    		case 'o':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			oOutFile = optarg;
    			break;
    		case 'e':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			oFileExt = optarg;
    			break;
    		case 't':
    			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
    			threads = atoi(optarg);
    			break;
    		case  1:
    			bRandom = 1;
    			break;
    		case 'r':
    			recursive = 1;
    			break;
    		case 'n':
    			nodetail = 1;
    			break;
    		case 'v':
    			verbose = 1;
    			break;
    		case '?':
    		case ':':
    		case 'h':
    			helpinfo();
    			return 0;
    			break;
    		default:
    			/* You won't actually get here. */
    			break;
    		}
    		opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
    	}
    	// Process Parameters
    	f_ExitIfTure(oPath.empty(), "please input path name, format : -p pathname");
    	f_ExitIfTure(oMode.empty(), "please input file name, format : -f filename");
    
    	srand((unsigned)time(NULL));
    
    #ifdef WIN32
    	if (oPath[oPath.length() - 1] != '\')
    		oPath += '\';
    #else
    	if (oPath[oPath.length() - 1] != '/')
    		oPath += '/';
    #endif
    	pszLocalPath = oPath.c_str();
    
    	if (oMode == "whole" || oMode == "1")
    		mode = 1;
    	else if (oMode == "512" || oMode == "2")
    		mode = 2;
    	else if (oMode == "3")
    		mode = 3;
    	else{
    		cout << "Mode ERROR!" << endl;
    		return 1;
    	}
    
    	if (oOutFile.empty())
    		oOutFile = (CPLString)DateTimeStr() + ".txt";
    
    	if (oFileExt.empty())
    		oFileExt = ".tif";
    	else
    		oFileExt = '.' + oFileExt;
    	if (deapth == 0)
    		deapth = 100;
    
    
    	getFiles(pszLocalPath, files);
    	for (vector<string>::iterator iter = files.begin(); iter != files.end();){
    		CPLString ext = (*iter).c_str() + (*iter).find_last_of('.');
    		if (ext != oFileExt){
    			iter = files.erase(iter);
    			continue;
    		}
    		iter++;
    	}
    	file_num = files.size();
    
    
    	//打开输出文件
    	coutBuf = cout.rdbuf();				// Save cout stream buffer pointer
    	of.open(oOutFile.c_str(), ios::app);	    // Gets the file out.txt stream buffer pointer
    	if (of.fail()){
    		cout << "Unable to create file: " << oOutFile << ", the file name can not contain" \ / : * ? " < > | "" << endl;
    		exit(1);
    	}
    	fileBuf = of.rdbuf();
    
    	//start timing
    	long timeuse_ms;
    #ifdef WIN32
    	//	DWORD t1 = 0, t2 = 0;
    	LARGE_INTEGER nTime1, nTime2, tc;
    	QueryPerformanceFrequency(&tc);
    	QueryPerformanceCounter(&nTime1);
    	//	t1 = GetTickCount();
    #else
    	struct timeval t1, t2;
    	gettimeofday(&t1, NULL);
    #endif
    	//分配内存	
    	if (threads == 0)
    		threads = 1;
    	if (mode == 2 || mode == 3){
    		for (int i = 0; i < threads; i++)
    			pblock512buff[i] = (GByte *)CPLMalloc(MALLOC521BLOCKSIZE);
    	}
    	//收集文件信息
    	GatherFilesInfo();
    
    	//输出初步信息
    	str_print.append("  Command: gdalread ");
    	for (int i = 1; i < argc; i++)
    		str_print.append(argv[i]).append(" ");
    	char buff[200];
    	str_print.append("
      File number: ");
    	sprintf(buff, "%d", files.size());
    	str_print.append(buff);
    	str_print.append("
      Total file size: ");
    	sprintf(buff, "%d", TotalFilesSize / (1024 * 1024));
    	str_print.append(buff).append("M -- ");
    	sprintf(buff, "%.3f", TotalFilesSize * 1.0 / (1024 * 1024 * 1024));
    	str_print.append(buff).append("G
    ");
    	str_print.append(SPLITLINE).append("
      ");
    	sprintf(buff, "%-40s", "FILE_NAME"); str_print.append(buff);
    	sprintf(buff, "%-6s", "PID"); str_print.append(buff);
    	sprintf(buff, "%-8s", "SIZE/M"); str_print.append(buff);
    	sprintf(buff, "%-18s", "X*Y/BANDS/DEAP"); str_print.append(buff);
    	sprintf(buff, "%-7s", "LAYER"); str_print.append(buff);
    	sprintf(buff, "%-42s", "EXTRACTION"); str_print.append(buff);
    	sprintf(buff, "%-10s", "TIME/sec"); str_print.append(buff);
    	sprintf(buff, "%-10s", "SPEED M/s
    "); str_print.append(buff);
    
    	//计算执行任务
    	//输出详细信息
    	if (mode == 1){
    		AssignTask_mode1();
    		if (bRandom == 1)
    			sort(AllTask.begin(), AllTask.end(), compare);
    		StartThread();
    		WaitUntilFinished();
    	}
    	else if (mode == 2){
    		AssignTask_mode2();
    		if (bRandom == 1)
    			sort(AllTask.begin(), AllTask.end(), compare);
    		StartThread();
    		WaitUntilFinished();
    	}
    	else if (mode == 3){
    		if (setedlayer == 0){
    			curlayer = 1;
    			while (curlayer <= deapth && AssignTask_mode3(curlayer) != 0){
    				if (bRandom == 1)
    					sort(AllTask.begin(), AllTask.end(), compare);
    				//开始计时
    
    				long timeuse_ms_lt;
    #ifdef WIN32
    				LARGE_INTEGER nTime1_lt, nTime2_lt, tc_lt;
    				QueryPerformanceFrequency(&tc_lt);
    				QueryPerformanceCounter(&nTime1_lt);
    #else
    				struct timeval t1_lt, t2_lt;
    				gettimeofday(&t1_lt, NULL);
    #endif
    				//执行任务
    				taskg_num = 0;
    				ThreadRetFlagPos = 0;
    				memset(ThreadRetFlag, 0, MAXTHREADNUM);
    				StartThread();
    				WaitUntilFinished();
    				curlayer++;
    				//结束计时
    #ifdef WIN32
    				QueryPerformanceCounter(&nTime2_lt);
    				timeuse_ms_lt = (nTime2_lt.QuadPart - nTime1_lt.QuadPart)*1000.0 / tc_lt.QuadPart;
    #else
    				gettimeofday(&t2_lt, NULL);
    				timeuse_ms_lt = (t2_lt.tv_sec - t1_lt.tv_sec) * 1000 + (t2_lt.tv_usec - t1_lt.tv_usec) / 1000;
    #endif
    				//输出计时
    				char buff[200];
    				sprintf(buff, "  Time consumpted of this layer is: %.3f seconds.
    
    ", timeuse_ms_lt / 1000.0);
    				str_print.append(buff);
    			}
    		}
    		else{
    			curlayer = setedlayer;
    			if (AssignTask_mode3(setedlayer) != 0){
    				if (bRandom == 1)
    					sort(AllTask.begin(), AllTask.end(), compare);
    				StartThread();
    				WaitUntilFinished();
    			}
    		}
    	}
    	//任务结束
    
    #ifdef WIN32
    	QueryPerformanceCounter(&nTime2);
    	timeuse_ms = (nTime2.QuadPart - nTime1.QuadPart)*1000.0 / tc.QuadPart;
    #else
    	gettimeofday(&t2, NULL);
    	timeuse_ms = (t2.tv_sec - t1.tv_sec) * 1000 + (t2.tv_usec - t1.tv_usec) / 1000;
    #endif
    
    	//输出总结信息
    
    	if (mode == 2 || mode == 3){
    		for (int i = 0; i < threads; i++)
    			CPLFree(pblock512buff[i]);
    	}
    	CPLString sum_print;
    
    	sprintf(buff, "
      The Total Time Cost is    :%.3f seconds.   
    ", timeuse_ms / 1000.0);
    	sum_print.append(buff);
    
    	if (mode == 1 || mode == 2){
    		sprintf(buff, "  The Average Read Speed is :%.3f M/s.
    ", (TotalFilesSize * 1.0 / (1024 * 1024)) / (timeuse_ms / 1000.0));
    		sum_print.append(buff);
    	}
    	sum_print.append("  ---Finished!---
    ");
    	cout << sum_print;
    
    	cout.rdbuf(fileBuf);	            // Sets the cout stream buffer pointer to the out.txt stream buffer pointer
    	cout << sum_print;
    	of.flush();
    	of.close();
    	cout.rdbuf(coutBuf);
    
    	return 0;
    }
    
    /************************************************************************/
    /*          Thread      WaitUntilFinished()                             */
    /************************************************************************/
    
    void WaitUntilFinished(void)
    {
    	bool bFinished = 0;
    	while (bFinished == 0){
    		bFinished = 1;
    		for (int i = 0; i < threads; i++){
    			if (ThreadRetFlag[i] == 0)
    				bFinished = 0;
    		}
    		//打印输出
    #define BUFFSIZE_L 1024000
    		static char buff[BUFFSIZE_L];
    		int curpos = str_print.size();
    		if (curpos < BUFFSIZE_L && str_print_pos < curpos - 1){
    			CPLSleep(0.001);
    			memcpy(buff, str_print.c_str() + str_print_pos, curpos - str_print_pos);
    			buff[curpos - str_print_pos] = 0;
    			cout << buff;
    
    			cout.rdbuf(fileBuf);	            // Sets the cout stream buffer pointer to the out.txt stream buffer pointer
    			cout << buff;
    			of.flush();
    			cout.rdbuf(coutBuf);
    
    			str_print_pos = curpos;
    		}
    	}
    }
    
    /************************************************************************/
    /*          Thread            StartThread()                             */
    /************************************************************************/
    
    void StartThread(void)
    {
    	for (int i = 0; i < threads; i++){
    		CPLCreateThread(PerformThread, NULL);
    		CPLSleep(0.025);
    	}
    }
    
    /************************************************************************/
    /*          Thread           PerformThread()                            */
    /************************************************************************/
    
    static CPLMutex	*hMutex = NULL;
    static CPLMutex	*hMutex2 = NULL;
    //unsigned __stdcall PerformThread(void* parg)
    void PerformThread(void* parg)
    
    {
    	TASKGROUP CurrTaskGroup;
    	int curr_num;
    	GIntBig PID = CPLGetPID();
    
    	CPLCreateOrAcquireMutex(&hMutex, 0);
    	int ThisThreadRetFlagPos = ThreadRetFlagPos++;
    	CPLReleaseMutex(hMutex);
    
    	GByte * pafScanline = NULL;
    
    	if (mode == 2 || mode == 3)
    		pafScanline = pblock512buff[ThisThreadRetFlagPos];
    
    	GDALDataset* poDataset = NULL;
    	const char* last_filepath = NULL;
    
    	while (1){
    		//Get TaskGroup
    		CPLCreateOrAcquireMutex(&hMutex2, 0);
    		if (taskg_num > AllTask.size() - 1){
    			CPLReleaseMutex(hMutex2);
    			ThreadRetFlag[ThisThreadRetFlagPos] = 1;
    			return;
    		}
    		CurrTaskGroup = AllTask.at(taskg_num++);
    		//printf("%d
    ", taskg_num-1);
    		CPLReleaseMutex(hMutex2);
    
    		if (mode == 1)
    			pafScanline = (GByte *)CPLMalloc(CurrTaskGroup.at(0).SIZE_OUT_X * CurrTaskGroup.at(0).SIZE_OUT_Y*CurrTaskGroup.at(0).bands*CurrTaskGroup.at(0).deap);
    
    		if (CurrTaskGroup.at(0).filepath != last_filepath){
    			poDataset = (GDALDataset*)GDALOpen(CurrTaskGroup.at(0).filepath, GA_ReadOnly);
    			last_filepath = CurrTaskGroup.at(0).filepath;
    		}
    
    		//#undef WIN32
    		float timeuse_ms_g;
    #ifdef WIN32
    		LARGE_INTEGER nTime1_g, nTime2_g, tc_g;
    #else
    		struct timeval t1_g, t2_g;
    #endif
    		if (nodetail == 0 && verbose == 0){
    			//开始组计时	
    #ifdef WIN32
    			QueryPerformanceFrequency(&tc_g);
    			QueryPerformanceCounter(&nTime1_g);
    #else
    			gettimeofday(&t1_g, NULL);
    #endif 
    		}
    
    		for (int i = 0; i < CurrTaskGroup.size(); i++){
    			float timeuse_ms_s;
    #ifdef WIN32
    			LARGE_INTEGER nTime1_s, nTime2_s, tc_s;
    #else
    			struct timeval t1_s, t2_s;
    #endif
    			if (nodetail == 0 && verbose == 1){
    				//开始单任务计时		
    #ifdef WIN32
    				QueryPerformanceFrequency(&tc_s);
    				QueryPerformanceCounter(&nTime1_s);
    #else
    				gettimeofday(&t1_s, NULL);
    #endif
    			}
    			CPLErr err = poDataset->RasterIO(GF_Read, CurrTaskGroup.at(i).START_X, CurrTaskGroup.at(i).START_Y, 
    				CurrTaskGroup.at(i).SIZE_X, CurrTaskGroup.at(i).SIZE_Y, 
    				pafScanline, CurrTaskGroup.at(i).SIZE_OUT_X, CurrTaskGroup.at(i).SIZE_OUT_Y, 
    				GDALDataType(CurrTaskGroup.at(i).deap), CurrTaskGroup.at(i).bands, bound_map, 0, 0, 0);
    			if (nodetail == 0 && verbose == 1){
    				//结束单任务计时		
    #ifdef WIN32
    				QueryPerformanceCounter(&nTime2_s);
    				timeuse_ms_s = (nTime2_s.QuadPart - nTime1_s.QuadPart)*1000.0 / tc_s.QuadPart;
    #else
    				gettimeofday(&t2_s, NULL);
    				timeuse_ms_s = (t2_s.tv_sec - t1_s.tv_sec) * 1000 + (t2_s.tv_usec - t1_s.tv_usec) / 1000;
    #endif		
    				//打印输出
    				CPLString osOut;
    				TaskOutput(&CurrTaskGroup.at(i), timeuse_ms_s, osOut, PID);
    				str_print.append(osOut.c_str());
    			}
    		}
    
    		if (nodetail == 0 && verbose == 0){
    			//结束组计时		
    #ifdef WIN32
    			QueryPerformanceCounter(&nTime2_g);
    			timeuse_ms_g = (nTime2_g.QuadPart - nTime1_g.QuadPart)*1000.0 / tc_g.QuadPart;
    #else
    			gettimeofday(&t2_g, NULL);
    			timeuse_ms_g = (t2_g.tv_sec - t1_g.tv_sec) * 1000 + (t2_g.tv_usec - t1_g.tv_usec) / 1000;
    #endif		
    			//打印输出
    			CPLString osOut;
    			TaskGroupOutput(&CurrTaskGroup, timeuse_ms_g, osOut, PID);
    			str_print.append(osOut.c_str());
    		}
    
    		if (mode == 1){
    			CPLFree(pafScanline);
    			pafScanline = NULL;
    		}
    	}
    }
    
    /************************************************************************/
    /*                             TaskGroupOutput()                             */
    /************************************************************************/
    void TaskGroupOutput(TASKGROUP* taskg, float timeuse_ms, CPLString & osOut, GIntBig PID)
    {
    	osOut.clear();
    	char buff[100];
    
    	osOut.append("  ");
    	sprintf(buff, "%-40.38s", CPLGetFilename(taskg->at(0).filepath));	osOut.append(buff);
    	sprintf(buff, "%-6d", PID);									osOut.append(buff);
    	sprintf(buff, "%-8s", "");									osOut.append(buff);
    
    	sprintf(buff, "%d", taskg->at(0).f_sizex);
    	string of_xyb = buff;
    	sprintf(buff, "%d", taskg->at(0).f_sizey);
    	of_xyb = of_xyb + '*' + buff + '/';
    	sprintf(buff, "%d", taskg->at(0).bands);
    	of_xyb = of_xyb + buff + '/';
    	sprintf(buff, "%d", taskg->at(0).deap);
    	of_xyb = of_xyb + buff;
    
    	sprintf(buff, "%-18.18s", of_xyb.c_str());					osOut.append(buff);
    
    	if (mode == 3){
    		sprintf(buff, "%-7d", curlayer);						osOut.append(buff);
    	}
    	else if (mode == 1 || mode == 2){
    		sprintf(buff, "%-7s", "");								osOut.append(buff);
    	}
    
    	sprintf(buff, "%d", taskg->size());
    	string of_extr = buff; of_extr += "*";
    	sprintf(buff, "(%d", taskg->at(0).START_X);
    	of_extr = of_extr + buff;
    	sprintf(buff, "%d", taskg->at(0).START_Y);
    	of_extr = of_extr + ',' + buff + "):(";
    	sprintf(buff, "%d", taskg->at(0).SIZE_X);
    	of_extr = of_extr + buff + '*';
    	sprintf(buff, "%d", taskg->at(0).SIZE_Y);
    	of_extr = of_extr + buff + ")->(";
    	sprintf(buff, "%d", taskg->at(0).SIZE_OUT_X);
    	of_extr = of_extr + buff + "*";
    	sprintf(buff, "%d", taskg->at(0).SIZE_OUT_Y);
    	of_extr = of_extr + buff + ")";
    
    	sprintf(buff, "%-42.40s", of_extr.c_str());					osOut.append(buff);
    	sprintf(buff, "%-10.3f", timeuse_ms / 1000.0);				osOut.append(buff);
    
    	if (mode == 1 || mode == 2){
    		unsigned long  amount = taskg->size() * taskg->at(0).SIZE_X * taskg->at(0).SIZE_Y * taskg->at(0).bands * taskg->at(0).deap;
    		float speed = amount * 1000.0 / (1024 * 1024 * timeuse_ms);
    		sprintf(buff, "%-10.1f
    ", speed);
    	}
    	else{
    		sprintf(buff, "%-10.1s
    ", "");
    	}
    	osOut.append(buff);
    
    }
    
    /************************************************************************/
    /*                             TaskOutput()                             */
    /************************************************************************/
    void TaskOutput(TASK* task, float timeuse_ms, CPLString & osOut, GIntBig PID)
    {
    	osOut.clear();
    	char buff[100];
    
    	osOut.append("  ");
    	sprintf(buff, "%-40.38s", CPLGetFilename(task->filepath));	osOut.append(buff);
    	sprintf(buff, "%-6d", PID);									osOut.append(buff);
    	sprintf(buff, "%-8s", "");									osOut.append(buff);
    
    	sprintf(buff, "%d", task->f_sizex);
    	string of_xyb = buff;
    	sprintf(buff, "%d", task->f_sizey);
    	of_xyb = of_xyb + '*' + buff + '/';
    	sprintf(buff, "%d", task->bands);
    	of_xyb = of_xyb + buff + '/';
    	sprintf(buff, "%d", task->deap);
    	of_xyb = of_xyb + buff;
    
    	sprintf(buff, "%-18.18s", of_xyb.c_str());					osOut.append(buff);
    
    	if (mode == 3){
    		sprintf(buff, "%-7d", curlayer);						osOut.append(buff);
    	}
    	else if (mode == 1 || mode == 2){
    		sprintf(buff, "%-7s", "");								osOut.append(buff);
    	}
    
    
    	sprintf(buff, "(%d", task->START_X);
    	string of_extr = buff;
    	sprintf(buff, "%d", task->START_Y);
    	of_extr = of_extr + ',' + buff + "):(";
    	sprintf(buff, "%d", task->SIZE_X);
    	of_extr = of_extr + buff + '*';
    	sprintf(buff, "%d", task->SIZE_Y);
    	of_extr = of_extr + buff + ")->(";
    	sprintf(buff, "%d", task->SIZE_OUT_X);
    	of_extr = of_extr + buff + "*";
    	sprintf(buff, "%d", task->SIZE_OUT_Y);
    	of_extr = of_extr + buff + ")";
    
    	sprintf(buff, "%-42.40s", of_extr.c_str());					osOut.append(buff);
    	sprintf(buff, "%-10.3f", timeuse_ms / 1000.0);				osOut.append(buff);
    
    	if (mode == 1 || mode == 2){
    		unsigned long  amount = task->SIZE_X * task->SIZE_Y * task->bands * task->deap;
    		float speed = amount * 1000.0 / (1024 * 1024 * timeuse_ms);
    		sprintf(buff, "%-10.1f
    ", speed);
    	}
    	else{
    		sprintf(buff, "%-10.1s
    ", "");
    	}
    	osOut.append(buff);
    
    }
    
    /************************************************************************/
    /*                           GatherFilesInfo()                          */
    /************************************************************************/
    
    void GatherFilesInfo(void)
    {
    	info Info;
    	vector<info>::iterator infoiter;
    	for (vector<string>::iterator iter = files.begin(); iter != files.end(); iter++){
    
    		Info.filepath = (*iter).c_str();
    		//get filesize
    		VSILFILE *fpL = NULL;
    		fpL = VSIFOpenL((*iter).c_str(), "rb");
    		if (fpL == NULL)
    		{
    			cout << "VSIFOpenL(...) Open File: " << (*iter).c_str() << " Failed!" << endl;
    			exit(1);
    		}
    		GUIntBig nFileSize;
    		VSIFSeekL(fpL, 0, SEEK_END);
    		nFileSize = VSIFTellL(fpL);
    		VSIFCloseL(fpL);
    		fpL = NULL;
    		Info.SIZE = nFileSize;
    		TotalFilesSize += nFileSize;
    
    		GDALDataset *poDataset;
    		poDataset = (GDALDataset*)GDALOpen((*iter).c_str(), GA_ReadOnly);
    
    		if (!poDataset){
    			cout << "GDALOpen(...) Open File: " << (*iter).c_str() << " Failed!" << endl;
    			exit(1);
    		}
    
    		Info.bands = poDataset->GetRasterCount();
    		Info.SIZE_X = poDataset->GetRasterXSize();
    		Info.SIZE_Y = poDataset->GetRasterYSize();
    		Info.deap = poDataset->GetRasterBand(1)->GetRasterDataType();
    
    		infoiter = FilesInfo.insert(FilesInfo.end(), Info);
    	}
    }
    
    /************************************************************************/
    /*                           AssignTask_mode1()                         */
    /************************************************************************/
    void AssignTask_mode1(void)
    {
    	TASK task;
    	TASKGROUP taskg;
    	vector<TASK>::iterator iter_taskg;
    	vector<TASKGROUP>::iterator iter_atask;
    
    	for (vector<info>::iterator iter = FilesInfo.begin(); iter != FilesInfo.end(); iter++){
    		task.filepath = (*iter).filepath;
    		if ((*iter).SIZE > MAXBUFSIZE){
    			task.START_X = 0;
    			task.SIZE_X = (*iter).SIZE_X;
    			task.SIZE_OUT_X = (*iter).SIZE_X;
    			int SIZE_Y_R = MAXBUFSIZE / ((*iter).SIZE_X *(*iter).bands * (*iter).deap);
    
    			for (int i = 0; i <= (*iter).SIZE_Y / SIZE_Y_R; i++){
    				task.START_Y = SIZE_Y_R * i;
    				task.SIZE_Y = SIZE_Y_R;
    				if (i == (*iter).SIZE_Y / SIZE_Y_R)
    					task.SIZE_Y = (*iter).SIZE_Y % SIZE_Y_R;
    				task.SIZE_OUT_Y = task.SIZE_Y;
    				task.bands = (*iter).bands;
    				task.deap = (*iter).deap;
    				task.rand = rand();
    				task.f_sizex = (*iter).SIZE_X;
    				task.f_sizey = (*iter).SIZE_Y;
    				taskg.clear();
    				iter_taskg = taskg.insert(taskg.end(), task);
    				iter_atask = AllTask.insert(AllTask.end(), taskg);
    			}
    		}
    		else{
    			task.START_X = task.START_Y = 0;
    			task.SIZE_X = (*iter).SIZE_X;
    			task.SIZE_Y = (*iter).SIZE_Y;
    			task.SIZE_OUT_X = (*iter).SIZE_X;
    			task.SIZE_OUT_Y = (*iter).SIZE_Y;
    			task.bands = (*iter).bands;
    			task.deap = (*iter).deap;
    			task.rand = rand();
    			task.f_sizex = (*iter).SIZE_X;
    			task.f_sizey = (*iter).SIZE_Y;
    			taskg.clear();
    			iter_taskg = taskg.insert(taskg.end(), task);
    			iter_atask = AllTask.insert(AllTask.end(), taskg);
    		}
    	}
    }
    /************************************************************************/
    /*                           AssignTask_mode2()                         */
    /************************************************************************/
    
    void AssignTask_mode2(void)
    {
    	TASK task;
    	TASKGROUP taskg;
    	vector<TASK>::iterator iter_taskg;
    	vector<TASKGROUP>::iterator iter_atask;
    
    	for (vector<info>::iterator iter = FilesInfo.begin(); iter != FilesInfo.end(); iter++){
    		task.filepath = (*iter).filepath;
    		for (int iy = 0; iy <= (*iter).SIZE_Y / 512; iy++){ //y axis
    			taskg.clear();
    			for (int ix = 0; ix <= (*iter).SIZE_X / 512; ix++) //x axis
    			{
    				ix == (*iter).SIZE_X / 512 ? task.SIZE_X = (*iter).SIZE_X % 512 : task.SIZE_X = 512;
    				iy == (*iter).SIZE_Y / 512 ? task.SIZE_Y = (*iter).SIZE_Y % 512 : task.SIZE_Y = 512;
    				task.START_X = 512 * ix;
    				task.START_Y = 512 * iy;
    				task.SIZE_OUT_X = task.SIZE_X;
    				task.SIZE_OUT_Y = task.SIZE_Y;
    				task.bands = (*iter).bands;
    				task.deap = (*iter).deap;
    				task.rand = rand();
    				task.f_sizex = (*iter).SIZE_X;
    				task.f_sizey = (*iter).SIZE_Y;
    				iter_taskg = taskg.insert(taskg.end(), task);
    			}
    			iter_atask = AllTask.insert(AllTask.end(), taskg);
    		}
    	}
    }
    
    /************************************************************************/
    /*                           AssignTask_mode3()                         */
    /************************************************************************/
    
    int AssignTask_mode3(int count)
    {
    	TASK task;
    	TASKGROUP taskg;
    	vector<TASK>::iterator iter_taskg;
    	vector<TASKGROUP>::iterator iter_atask;
    	int times = pow(2, count - 1);
    	int taskg_count = 0;
    
    	AllTask.clear();
    	for (vector<info>::iterator iter = FilesInfo.begin(); iter != FilesInfo.end(); iter++){
    		task.filepath = (*iter).filepath;
    		int maxXY = (*iter).SIZE_X > (*iter).SIZE_Y ? (*iter).SIZE_X : (*iter).SIZE_Y;
    		int stepleng = maxXY / times;
    
    		if (stepleng <= 512 / 2)
    			continue;
    
    		if (count == 1){
    			task.START_X = 0;
    			task.START_Y = 0;
    			task.SIZE_X = (*iter).SIZE_X;
    			task.SIZE_Y = (*iter).SIZE_Y;
    			task.SIZE_OUT_X = 512 * task.SIZE_X / maxXY;
    			task.SIZE_OUT_Y = 512 * task.SIZE_Y / maxXY;
    			task.bands = (*iter).bands;
    			task.deap = (*iter).deap;
    			task.rand = rand();
    			task.f_sizex = (*iter).SIZE_X;
    			task.f_sizey = (*iter).SIZE_Y;
    			taskg.clear();
    			iter_taskg = taskg.insert(taskg.end(), task);
    			iter_atask = AllTask.insert(AllTask.end(), taskg);
    			taskg_count++;
    		}
    		else{
    			for (int iy = 0; iy <= ((*iter).SIZE_Y - 1) / stepleng && iy < times; iy++){
    				taskg.clear();
    				for (int ix = 0; ix <= ((*iter).SIZE_X - 1) / stepleng && ix < times; ix++){
    					task.START_X = stepleng * ix;
    					task.START_Y = stepleng * iy;
    
    					if (ix == ((*iter).SIZE_X - 1) / stepleng){
    						task.SIZE_X = ((*iter).SIZE_X - 1) % stepleng + 1;
    						task.SIZE_OUT_X = 512 * task.SIZE_X / stepleng;
    					}
    					else{
    						task.SIZE_X = stepleng;
    						task.SIZE_OUT_X = 512;
    					}
    
    					if (iy == ((*iter).SIZE_Y - 1) / stepleng){
    						task.SIZE_Y = ((*iter).SIZE_Y - 1) % stepleng + 1;
    						task.SIZE_OUT_Y = 512 * task.SIZE_Y / stepleng;
    					}
    					else{
    						task.SIZE_Y = stepleng;
    						task.SIZE_OUT_Y = 512;
    					}
    					task.bands = (*iter).bands;
    					task.deap = (*iter).deap;
    					task.rand = rand();
    					task.f_sizex = (*iter).SIZE_X;
    					task.f_sizey = (*iter).SIZE_Y;
    					iter_taskg = taskg.insert(taskg.end(), task);
    				}
    				iter_atask = AllTask.insert(AllTask.end(), taskg);
    				taskg_count++;
    			}//onefile
    		}
    	}//allfile
    	return taskg_count;
    }
    
    /************************************************************************/
    /*                            f_ExitIfTure()                            */
    /************************************************************************/
    void f_ExitIfTure(int val, const char* pstr)
    {
    	if (val == 1){
    		cout << "ERROR! " << (pstr ? pstr : "") << endl;
    		exit(1);
    		return;
    	}
    }
    
    /************************************************************************/
    /*                              getFiles()                              */
    /************************************************************************/
    #ifdef WIN32
    void getFiles(string path, vector<string>& files)
    {
    	if (path.at(path.length() - 1) == '\')
    		path.erase(path.length() - 1);
    	long   hFile = 0;				//File hadle
    	struct _finddata_t fileinfo;	//File info
    	string p;
    	if ((hFile = _findfirst(p.assign(path).append("\*").c_str(), &fileinfo)) != -1)
    	{
    		do
    		{	//If it is a directory, iteration, if not, join the list
    			if ((fileinfo.attrib &  _A_SUBDIR) && recursive == 1)
    			{
    				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
    					getFiles(p.assign(path).append("\").append(fileinfo.name), files);
    			}
    			else
    			{
    				files.push_back(p.assign(path).append("\").append(fileinfo.name));
    			}
    		} while (_findnext(hFile, &fileinfo) == 0);
    		_findclose(hFile);
    	}
    }
    #else
    void getFiles(string o_path, vector<string>& files)
    {
    	if (o_path.at(o_path.length() - 1) == '/')
    		o_path.erase(o_path.length() - 1);
    	const char *path = o_path.c_str();
    	DIR		*pDir;
    	struct dirent	*ent;
    	int		i = 0;
    	char	childpath[512];
    
    	pDir = opendir(path);
    	memset(childpath, 0, sizeof(childpath));
    	string p;
    	while ((ent = readdir(pDir)) != NULL){
    		if (ent->d_type & DT_DIR && recursive == 1){
    			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
    				continue;
    			sprintf(childpath, "%s/%s", path, ent->d_name);
    			getFiles(childpath, files);
    		}
    		else /*if(ent->d_type & DT_REG)*/{
    			files.push_back(p.assign(path).append("/").append(ent->d_name));
    		}
    	}
    }
    
    #endif
    
    /************************************************************************/
    /*                            DateTimeStr()                             */
    /************************************************************************/
    char* DateTimeStr(void)
    {
    	time_t rawtime;
    	struct tm* timeinfo;
    	time(&rawtime);
    	timeinfo = localtime(&rawtime);
    	strftime(timE, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
    	return timE;
    }
    
  • 相关阅读:
    JDK1.8HashMap底层实现原理
    关于map转json,空key丢失的问题
    spring一些注解的使用及相关注解差异
    搭建基础项目遇到的一些小坑
    解析ftp上word文档的文字并输入
    R语言中回归模型预测的不同类型置信区间应用比较分析
    R语言中的广义线性模型(GLM)和广义相加模型(GAM):多元(平滑)回归分析保险资金投资组合信用风险敞口
    R语言对巨灾风险下的再保险合同定价研究案例:广义线性模型和帕累托分布Pareto distributions分析
    R语言中GLM(广义线性模型),非线性和异方差可视化分析
    如何用R语言绘制生成正态分布图表
  • 原文地址:https://www.cnblogs.com/oloroso/p/13372697.html
Copyright © 2011-2022 走看看