2012-03-21 41 views
1

私はSSDを持っており、プログラムのI/Oパフォーマンスをシミュレートするために使用しようとしていますが、プログラムから計算されたIOPSはIOMeterよりはるかに高速です。Windows C++のマルチスレッドIOPSがIOMeterよりも高速なのはなぜですか?

SSDはIOMeterのPLEXTOR PX-128M3Sで、最大512Bランダム読み出しIOPSは約94kです(キューの深さは32です)。 私のプログラム(Windowsスレッド32個)はIOMeterのおよそ5倍の約500k 512B IOPSに達することができます!私はデータ検証をしましたが、データフェッチでエラーは見つかりませんでした。それは私のデータが順番に取得されるからです。

私は(それは主にファイルから512Bを取得し、それを解放し、私は、プログラムロジックを検証するために、問題を見つけられませんでした4バイト(int)を使用しました)私のコードbelwoを貼り付け、誰もが私が間違っているところ私が把握することができ、 ?

ありがとうございます!

#include <stdio.h> 
    #include <Windows.h> 



    //Global variables 
    long completeIOs = 0; 
    long completeBytes = 0; 
    int threadCount = 32; 
    unsigned long long length = 1073741824;     //4G test file 

    int interval = 1024; 

    int resultArrayLen = 320000; 

    int *result = new int[resultArrayLen]; 

    //Method declarison 
    double GetSecs(void);        //Calculate out duration 
    int InitPool(long long,char*,int);     //Initialize test data for testing, if successful, return 1; otherwise, return a non 1 value. 
    int * FileRead(char * path); 
    unsigned int DataVerification(int*, int sampleItem);       //Verify data fetched from pool 

    int main() 
    { 
     int sampleItem = 0x1; 
     char * fPath = "G:\\workspace\\4G.bin"; 
     unsigned int invalidIO = 0; 

     if (InitPool(length,fPath,sampleItem)!= 1) 
      printf("File write err... \n"); 

     //start do random I/Os from initialized file 
     double start = GetSecs(); 

     int * fetchResult = FileRead(fPath); 

     double end = GetSecs(); 

     printf("File read IOPS is %.4f per second.. \n",completeIOs/(end - start)); 

     //start data validation, for 4 bytes fetch only 

    // invalidIO = DataVerification(fetchResult,sampleItem); 

    // if (invalidIO !=0) 
    // { 
    //  printf("Total invalid data fetch IOs are %d", invalidIO); 
    // } 

     return 0; 
    } 



    int InitPool(long long length, char* path, int sample) 
    { 
     printf("Start initializing test data ... \n"); 

     FILE * fp = fopen(path,"wb"); 

     if (fp == NULL) 
     { 
      printf("file open err... \n"); 
      exit (-1); 
     } 

     else         //initialize file for testing 
     { 
      fseek(fp,0L,SEEK_SET); 

      for (int i=0; i<length; i++) 
      { 
       fwrite(&sample,sizeof(int),1,fp); 
      } 

      fclose(fp); 

      fp = NULL; 

      printf("Data initialization is complete...\n"); 

      return 1; 

     } 
    } 

    double GetSecs(void) 

    { 
     LARGE_INTEGER frequency; 
     LARGE_INTEGER start; 

     if(! QueryPerformanceFrequency(&frequency)) 
      printf("QueryPerformanceFrequency Failed\n"); 

     if(! QueryPerformanceCounter(&start)) 
      printf("QueryPerformanceCounter Failed\n"); 

     return ((double)start.QuadPart/(double)frequency.QuadPart); 

    } 

    class input 
    { 
    public: 
     char *path; 
     int starting; 

     input (int st, char * filePath):starting(st),path(filePath){} 

    }; 

    //Workers 
    DWORD WINAPI FileReadThreadEntry(LPVOID lpThreadParameter) 
    { 
     input * in = (input*) lpThreadParameter; 

     char* path = in->path; 

     FILE * fp = fopen(path,"rb"); 

     int sPos = in->starting; 

    // int * result = in->r; 

     if(fp != NULL) 
     { 
      fpos_t pos; 
      for (int i=0; i<resultArrayLen/threadCount;i++) 
      { 

       pos = i * interval; 
       fsetpos(fp,&pos); 
       //For 512 bytes fetch each time 
       unsigned char *c =new unsigned char [512]; 
       if (fread(c,512,1,fp) ==1) 
       { 
        InterlockedIncrement(&completeIOs); 
        delete c; 
       } 

       //For 4 bytes fetch each time 
       /*if (fread(&result[sPos + i],sizeof(int),1,fp) ==1) 
       { 
        InterlockedIncrement(&completeIOs); 
       }*/ 

       else 
       { 
        printf("file read err...\n"); 
        exit(-1); 
       } 
      } 

      fclose(fp); 
      fp = NULL; 
      } 

     else 
     { 
      printf("File open err... \n"); 
      exit(-1); 
     } 
    } 

    int * FileRead(char * p) 
    { 
     printf("Starting reading file ... \n"); 


     HANDLE mWorkThread[256];      //max 256 threads 
     completeIOs = 0; 

     int slice = int (resultArrayLen/threadCount); 

     for(int i = 0; i < threadCount; i++) 
     { 
      mWorkThread[i] = CreateThread(
         NULL, 
         0, 
         FileReadThreadEntry, 
         (LPVOID)(new input(i*slice,p)), 
         0, 
         NULL); 
     } 

     WaitForMultipleObjects(threadCount, mWorkThread, TRUE, INFINITE); 

     printf("File read complete... \n"); 

     return result; 

    } 

    unsigned int DataVerification(int* result, int sampleItem) 
    { 
     unsigned int invalid = 0; 
     for (int i=0; i< resultArrayLen/interval;i++) 
     { 
      if (result[i]!=sampleItem) 
      { 
       invalid ++; 
       continue; 
      } 
     } 

     return invalid; 
    } 

答えて

4

私は特定であることを十分に詳細に見ていないが、私はそこに任意のコードがディスクにデータをフラッシュおよび/またはあなたの読み取りを保証するために表示されませんでしたが、実際にディスクから来ました。その場合、測定しているのは主にオペレーティングシステムのディスクキャッシュのパフォーマンスです。ディスクは測定しているパフォーマンスに少し貢献するかもしれませんが、他の要因を支配しているのはおそらくほんのわずかな貢献者でしょう。

コードは明らかにWindows用に記述されているため、CreateFileでファイルを開き、そのときにFILE_FLAG_NO_BUFFERINGフラグを渡すことが考えられます(例)。これは、少なくとも(ほとんどの場合)式からオペレーティングシステムのキャッシュを削除し、各読み取りまたは書き込みがディスク自体に直接対処するように強制します。

関連する問題