格式化与未格式化硬盘读取/ Wrtie问题

时间:2017-02-22 19:11:18

标签: c++ performance

我试图从两个固态硬盘(SSD)读取大量数据(~TB)(理想情况下是未格式化的),并通过某种算法合并数据并将其写回另一个SSD。最初我实现了一个程序,它从两个FORMATTED硬盘驱动器(OS看到它)读取并写入另一个格式化的硬盘驱动器。我能够获得大约450 MB /秒的速度(整个程序)。我正在使用fread()从SSD读取数据。

然后我通过从两个UNFORMATTED SSD读取并写入格式化的SSD来实现它,我只得到大约200 MB /秒。我仍在使用fread(),我很困惑为什么速度较慢。要读取未格式化的硬盘驱动器,我必须在管理模式下运行并使用HANDLE,然后在读取字节时将其转换为文件指针。因此,一旦找到正确的硬盘驱动器,代码是相同的,我正在使用freads()。下面列出了我用于测量格式化与未格式化读取速度的测试程序的代码。在这个程序中,我获得了大约200 MB /秒的UNFORMATTED硬盘读取和500 MB /秒的FORMATTED硬盘读取。

格式化的阅读程序。

while (tempCounter < frames_to_process)   //
{

    if (fread(frame_header_A, 1, 212052, pFile_A) != 212052) {

        printf("Couldn't read 212052 Bytes\n");
        if (feof(pFile_A))
        {
            printf("End of File reached while reading the frame\n");
            cout << "Num iterations " << tempCounter << endl;

        }
        if (ferror(pFile_A))
        {
            printf("Error reading file while reading for the frame\n");
        }

        time2 = chrono::high_resolution_clock::now();
        time_span = chrono::duration_cast<chrono::duration<double>>(time2 - time1);

        cout << "time to create imagery files " << setprecision(10) << time_span.count() << " seconds" << endl << endl;

        exit(0);
        return 0;

    }






    tempCounter++;


    //let's Check whether the variable end with 0xBCB55757


    container_count_A = 1;
    container_count_B = 2;

    if ((frame_header_A[212048] == (char)0xBC) && (frame_header_A[212049] == (char)0xB5) && (frame_header_A[212050] == (char)0x57) && (frame_header_A[212051] == (char)0x57))
    {
        unsigned int byte_1 = frame_header_A[27];
        unsigned int byte_2 = frame_header_A[26];
        unsigned int byte_3 = frame_header_A[25];
        unsigned int byte_4 = frame_header_A[24];

    }


}

未格式化读取程序。本质上,它迭代所有连接的硬盘驱动器,并使用某种模式找到特定的硬盘驱动器A和B.之后,HANDLE被转换为常规文件指针,然后重用上面的代码(格式化的情况)

FILE *pFile_A = NULL;
FILE *pFile_B = NULL;
FILE* f = NULL;


ofstream writeBinary_Combine;

writeBinary_Combine.open(argv[2], ofstream::out | ofstream::binary);
//


LPCTSTR dsksrc = L"\\\\.\\PhysicalDrive";
wchar_t dsk[512] = L"";


int fd;
bool channel_A_found = false;
bool channel_B_found = false;
char frame_header_A[212052];  //seems I can't have another 
char frame_header_B[212052];

unsigned int container_count_A = 1;
unsigned int container_count_B = 2;


char* frame_header_test = new char[212052];  // for some reason I am running out of static memory; so I am using heap to alleviate it ???


HANDLE hDisk;

for (int i = 0; i < 8; i++)
{


    swprintf(dsk, 511, L"%s%d", dsksrc, i);

    hDisk = CreateFile(dsk, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
    if (hDisk == INVALID_HANDLE_VALUE)
    {

        printf("%s%d%s", "couldn't open the drive ", i, "\n");
        CloseHandle(hDisk);
    }
    else
    {
        printf("%s%d%s", "successfully open the drive ", i, "\n");
        fd = _open_osfhandle((intptr_t)hDisk, _O_RDONLY);

        char buff_test[500000];
        if (fd != -1)
        {
            f = _fdopen(fd, "rb");
            int ret_code = 0;

            char drive_header[512];
            fread(drive_header, 1, 512, f);

            if ((drive_header[510] == (char)0x55) && (drive_header[511] == (char)0xAA))  //  test for a formatted drive; is there other identifiers?
            {
                //bootable drive; not an unformatted drive no need to keep on searching
                //_close(fd);
            }

            else
            {
                fseek(f, 0, SEEK_SET);
                ret_code = find_BCB55757(f, i);

                if (ret_code != -1)
                {
                    fseek(f, 0, SEEK_SET);
                    fread(buff_test, 1, ret_code, f);
                    fread(frame_header_test, 1, 212052, f);

                    unsigned int readout_B = 1;
                    unsigned int cmdout_B = 2;

                    unsigned int byte_1 = frame_header_test[115];
                    unsigned int byte_2 = frame_header_test[114];
                    unsigned int byte_3 = frame_header_test[113];
                    unsigned int byte_4 = frame_header_test[112];

                    readout_B = ((byte_4 << 24) & 0xff000000) | ((byte_3 << 16) & 0x00ff0000) | ((byte_2 << 8) & 0x0000ff00) | (byte_1 & 0x000000ff);

                    byte_1 = frame_header_test[123];
                    byte_2 = frame_header_test[122];
                    byte_3 = frame_header_test[121];
                    byte_4 = frame_header_test[120];

                    cmdout_B = ((byte_4 << 24) & 0xff000000) | ((byte_3 << 16) & 0x00ff0000) | ((byte_2 << 8) & 0x0000ff00) | (byte_1 & 0x000000ff);

                    //cout << readout_B << "  " << cmdout_B << endl;

                    size_t result_1 = 0;

                    if (readout_B == (cmdout_B - 1))
                    {
                        channel_B_found = true;
                        fseek(f, 0, SEEK_SET);              //this is the only way to do it
                        result_1 = fread(buff_test, 1, ret_code, f);

                        if (result_1 != (size_t)ret_code)
                        {
                            cout << "reading error 1 " << endl;
                            cout << "read bytes " << result_1 << endl;
                        }


                        result_1 = fread(frame_header_B, 1, 212052, f);
                        if (result_1 != (size_t)212052)
                        {
                            cout << "reading error 2" << endl;
                            cout << "read bytes " << result_1 << endl;
                        }

                        pFile_B = f;

                        byte_1 = frame_header_B[27];
                        byte_2 = frame_header_B[26];
                        byte_3 = frame_header_B[25];
                        byte_4 = frame_header_B[24];



                        cout << "found B" << endl;

                    }

                    else
                    {
                        channel_A_found = true;
                        fseek(f, 0, SEEK_SET);              //this is the only way to do it
                        result_1 = fread(buff_test, 1, ret_code, f);

                        if (result_1 != (size_t)ret_code)
                        {
                            cout << "reading error 5" << endl;
                            cout << "read bytes " << result_1 << endl;
                        }

                        result_1 = fread(frame_header_A, 1, 212052, f);

                        if (result_1 != (size_t)212052)
                        {
                            cout << "reading error 6" << endl;
                            cout << "read bytes " << result_1 << endl;
                        }

                        pFile_A = f;

                        byte_1 = frame_header_A[27];
                        byte_2 = frame_header_A[26];
                        byte_3 = frame_header_A[25];
                        byte_4 = frame_header_A[24];




                        cout << "found A" << endl;

                    }
                }
                //fclose(f);
            }
        }

        else
        {
            _close(fd);
        }

    }

    if (channel_A_found && channel_B_found)
    {
        cout << "both drives found" << endl;
        break;
    }
}// then reuse the code from the formatted case

以下是我的问题。

1)为什么未格式化的情况下的速度很慢,尽管我使用相同的fread()。是否与设置阅读物理驱动器HANDLE

有关

2)有没有办法提高未格式化硬盘的速度?我应该在未格式化的情况下使用read()而不是fread()吗?

我感谢任何帮助或想法!

0 个答案:

没有答案