QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 779|回复: 6

求助

[复制链接]
发表于 2005-2-2 18:00:46 | 显示全部楼层 |阅读模式
// burst.cpp : Defines the entry point for the console application.
//

#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <linux/param.h>

/////////////////////////////////////////////////////////////////////////////
// The one and only application object
#define BUFFERSIZE 1024*1024*10
#define WIBLOCK 30
long startSeconds;
long startMilli;
long finishSeconds;
long finishMilli;
long rate=0;
struct timeb* timeBuffer;
char FName[51][8]={"1.rar","2.rar","3.rar",
                                          "4.rar","5.rar","6.rar","7.rar",
                                          "8.rar","9.rar","10.rar","11.rar",
                                          "12.rar","13.rar","14.rar",
                                          "15.rar","16.rar","17.rar",
                                          "18.rar","19.rar","20.rar",
                                          "21.rar","22.rar","23.rar",
                                          "24.rar","25.rar","26.rar",
                                          "27.rar","28.rar","29.rar",
                                          "30.rar","31.rar","32.rar",
                                          "33.rar","34.rar","35.rar",
                                          "36.rar","37.rar","38.rar",
                                          "39.rar","40.rar","41.rar",
                                          "42.rar","43.rar","44.rar",
                                          "45.rar","46.rar","47.rar",
                                          "48.rar","49.rar","50.rar",
                                          "51.rar"};
char fileInBuffer[1024*500];
int randSelect[1024*1024];
long randNum=0;
static void *myProcess(void *arg);
int consol();
int threadNum;
int totalTimes=0;
int endFlag;
int g_iThreadNum;
int g_iFileNum;
int g_iBlockSize;
int g_iTotalBlocks;
int g_iThreadReadTimes;

int main()
{       
        long buffer[32767];
        int times;
        long k;
        long f;
        char fBuffer[200];
        while(!consol()){};
        endFlag=g_iThreadNum*g_iThreadReadTimes;
        threadNum=g_iThreadNum;
        sprintf(fBuffer,"***********************************************\n             Read test in linux!           \n                %dM/PER FILE             \n***********************************************\n\0",g_iTotalBlocks*g_iBlockSize);
        strcat(fileInBuffer,fBuffer);
        srand(time((time_t*)NULL));
        for(f=0;f<g_iFileNum*(g_iThreadNum);f++)
        {
                for(k=0;k<32767;k++)
                {
                        buffer[k]=rand();
                }
                randSelect[f]=(buffer[18000])%g_iFileNum;
        }
        timeBuffer=(struct timeb *)malloc(sizeof(struct timeb));
        ftime(timeBuffer);
        startSeconds = timeBuffer->time;
        startMilli=timeBuffer->millitm;
        for(times=0;times<g_iThreadNum;times++)
        {
                pthread_t pid;
                pthread_attr_t* attr;
                struct sched_param* param;
                param=(struct sched_param*)malloc(sizeof(struct sched_param));
                attr=(pthread_attr_t*)malloc(sizeof(pthread_attr_t));
                param->sched_priority=99;
                pthread_attr_init(attr);
                pthread_attr_setscope(attr,PTHREAD_SCOPE_SYSTEM);
                pthread_attr_setdetachstate(attr,PTHREAD_CREATE_DETACHED);
                pthread_attr_setschedpolicy(attr,SCHED_RR);
                pthread_attr_setschedparam(attr,param);
                pthread_create(&pid,attr,myProcess,NULL );
                //setpriority(PRIO_PROCESS,pid,-20);
                //*myProcess(NULL);
        }
        while(1){};
}

static void *myProcess(void *arg){

        int l_iFileSize;
        int handle;
        int readTimes;
        int currentID;
        int currentTimes;
        int localEndFlag;
        FILE *hfile;
        char *Bp;
        const char* p;
        char fBuffer[WIBLOCK];
        //long start, finish;
        long ownTimeStartSeconds,ownTimeFinishSeconds,ownTimeStartMilli,ownTimeFinishMilli;
        long perFileCost=0;
        threadNum--;
        currentID=threadNum;
        for(readTimes=0;readTimes<g_iThreadReadTimes;readTimes++){
                totalTimes++;
                currentTimes=totalTimes;
                p=FName[randSelect[currentID*g_iFileNum+readTimes]];
                hfile=fopen(p,"rb");
                Bp=(char*)malloc(BUFFERSIZE);

                ftime(timeBuffer);
                ownTimeStartSeconds = timeBuffer->time;
                ownTimeStartMilli=timeBuffer->millitm;
                for(l_iFileSize=0;l_iFileSize<g_iTotalBlocks;l_iFileSize++) fread(Bp,1024*1024*g_iBlockSize,1,hfile);
                ftime(timeBuffer);
                ownTimeFinishSeconds = timeBuffer->time;
                ownTimeFinishMilli=timeBuffer->millitm;
                ownTimeFinishMilli+=(ownTimeFinishSeconds-ownTimeStartSeconds)*1000;
                perFileCost=ownTimeFinishMilli-ownTimeStartMilli;
                endFlag--;
                localEndFlag=endFlag;
                //sprintf(fBuffer,"\n Thread %d Filename: %s Readtimes: %d Cost: %ld",currentID,p,currentTimes,perFileCost);
                sprintf(fBuffer,"\n Thread %d ",currentID);
                //myStrCat(fileInBuffer,fBuffer,sizeof(fileInBuffer),sizeof(fBuffer));
                strcat(fileInBuffer,fBuffer);
                sprintf(fBuffer,"Filename: %s ",p);
                strcat(fileInBuffer,fBuffer);
                sprintf(fBuffer,"Readtimes: %d ",currentTimes);
                strcat(fileInBuffer,fBuffer);
                sprintf(fBuffer,"Cost: %ldms ",perFileCost);
                strcat(fileInBuffer,fBuffer);
                rate+=(g_iTotalBlocks*g_iBlockSize*1024*1000)/(perFileCost);
                printf("\nThread %d Filename: %s Readtimes: %d Cost: %ld,Average Speed is %ld K/S",currentID,p,currentTimes,perFileCost,((g_iTotalBlocks*g_iBlockSize*1000*1024)/(perFileCost)));
                sprintf(fBuffer,"Rate: %ldK/S\n",((g_iTotalBlocks*g_iBlockSize*1000*1024)/(perFileCost)));
                strcat(fileInBuffer,fBuffer);
                free(Bp);
                fclose(hfile);
        }

        if(!localEndFlag) {
                ftime(timeBuffer);
                finishSeconds = timeBuffer->time;
                finishMilli=timeBuffer->millitm;
                finishMilli+=(finishSeconds-startSeconds)*1000;
                randNum+=finishMilli-startMilli;
                printf("\nThread number: %d File number: %d Block size: %dM Total times:%d Cost:%8ld  \n",g_iThreadNum,g_iFileNum,g_iBlockSize,g_iThreadNum*g_iThreadReadTimes,randNum);
                sprintf(fBuffer,"\nThread number: %d File number: %d ",g_iThreadNum,g_iFileNum);
                strcat(fileInBuffer,fBuffer);
                sprintf(fBuffer,"Block size: %dM Total times: %d Cost: %ldms ",g_iBlockSize,g_iThreadNum*g_iThreadReadTimes,randNum);
                strcat(fileInBuffer,fBuffer);
                sprintf(fBuffer,"Avrage Rate: %ldK/S \n",(rate/((g_iThreadNum)*g_iThreadReadTimes)));
                strcat(fileInBuffer,fBuffer);
                handle = creat("history.txt", S_IREAD | S_IWRITE);
                write(handle, fileInBuffer, strlen(fileInBuffer));
                close(handle);
        }
        return NULL;
}
int consol()
{
        printf("\nPlease input Thread number(integer): ");
        scanf("%d",&g_iThreadNum);
        printf("\nPlease input fileNum(integer): ");
        scanf("%d",&g_iFileNum);
        if ((g_iFileNum)>50){ printf("\n File number must <51");return 0;}
        printf("\nPlease input blockSize(integer): ");
        scanf("%d",&g_iBlockSize);
        printf("\nPlease input total blocks to read: ");
        scanf("%d",&g_iTotalBlocks);
        printf("\nPlease input ThreadReadTimes(per thread read times Integer type): ");
        scanf("%d",&g_iThreadReadTimes);
        return 1;
}

我写了个小程序比较linux和widows下多个线程读文件

结果发现在linux下不起子线程直接读文件的速度(45~50M/S),比起一个线程读文件(12~13M/S)快很多,改了改线程的设置结果还是差不多,谁能告诉我为什么啊~?
发表于 2005-2-2 20:15:10 | 显示全部楼层
多线程比单线程慢的原因不好说,快是绝对不可能的。

我想可能有几个原因。

1. 标准c的文件操作是在用户空间另开缓存的,缓存处理的问题。
2. 内核的文件缓存耗尽,多个线城造成内河不断刷新缓存。
回复

使用道具 举报

发表于 2005-2-2 20:17:48 | 显示全部楼层
没看程序,是多个线程同时读吗?
回复

使用道具 举报

 楼主| 发表于 2005-2-3 12:41:30 | 显示全部楼层
[quote:23ecb3e726="kakuyou"]多线程比单线程慢的原因不好说,快是绝对不可能的。

我想可能有几个原因。

1. 标准c的文件操作是在用户空间另开缓存的,缓存处理的问题。
2. 内核的文件缓存耗尽,多个线城造成内河不断刷新缓存。[/quote]

谢谢,不过单线程比两个线程也快的太夸张了啊~
回复

使用道具 举报

发表于 2005-2-3 16:14:34 | 显示全部楼层
[quote:c12354a58d="nigel_d"][quote:c12354a58d="kakuyou"]多线程比单线程慢的原因不好说,快是绝对不可能的。

我想可能有几个原因。

1. 标准c的文件操作是在用户空间另开缓存的,缓存处理的问题。
2. 内核的文件缓存耗尽,多个线城造成内河不断刷新缓存。[/quote]

谢谢,不过单线程比两个线程也快的太夸张了啊~ [/quote]

建议你用系统调用再重新侧一遍,系统调用在用户空间是不做缓存的。

linux下 open read write
windows下 CreateFile ReadFile WriteFile
回复

使用道具 举报

 楼主| 发表于 2005-2-5 09:33:51 | 显示全部楼层
:-( 试了,好象还是不够快,跟不起子线程直接用fread读差好远~
回复

使用道具 举报

 楼主| 发表于 2005-2-18 18:37:29 | 显示全部楼层
还有没有提速的方法了??

我用了read读的可是速度并没有明显的提高~~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-6 15:36 , Processed in 0.040512 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表