并行I / O SSD与HDD令人惊讶的结果

时间:2013-07-16 12:14:31

标签: c++ c io parallel-processing ssd

我的一些关于并行I / O的测试发生了一个非常奇怪的情况。这是情况..我有多个线程打开文件处理程序到同一个文件,并从文件的多个位置(均匀间隔)读取有限数量的字节并将其转储到数组中。一切都是通过boost线程完成的。现在,我假设硬盘由于随机访问寻求应该更慢。这就是我的测试实际上针对SSD的原因。事实证明,与HDD相比,从固态磁盘读取相同文件时几乎没有任何加速。不知道问题可能是什么?对我来说这似乎是非常令人惊讶的/我也在下面发布我的代码,看看我到底在做什么:

    void readFunctor(std::string pathToFile, size_t filePos, BYTE* buffer, size_t buffPos, size_t dataLn, boost::barrier& barier) {

        FILE* pFile;
        pFile = fopen(pathToFile.c_str(), "rb");

        fseek(pFile, filePos, SEEK_SET);
        fread(buffer, sizeof(BYTE), dataLn, pFile);

        fclose(pFile);
        barier.wait();

    }

    void joinAllThreads(std::vector<boost::shared_ptr<boost::thread> > &threads) {

        for (std::vector<boost::shared_ptr<boost::thread> >::iterator it = threads.begin(); it != threads.end(); ++it) {
            (*it).get()->join();

        }

    }

    void readDataInParallel(BYTE* buffer, std::string pathToFile, size_t lenOfData, size_t numThreads) {
        std::vector<boost::shared_ptr<boost::thread> > threads;
        boost::barrier barier(numThreads);
        size_t dataPerThread = lenOfData / numThreads;

        for (int var = 0; var < numThreads; ++var) {
            size_t filePos = var * dataPerThread;
            size_t bufferPos = var * dataPerThread;
            size_t dataLenForCurrentThread = dataPerThread;
            if (var == numThreads - 1) {
                dataLenForCurrentThread = dataLenForCurrentThread + (lenOfData % numThreads);
            }

            boost::shared_ptr<boost::thread> thread(
                    new boost::thread(readFunctor, pathToFile, filePos, buffer, bufferPos, dataLenForCurrentThread, boost::ref(barier)));
            threads.push_back(thread);

        }

        joinAllThreads(threads);

    }

现在..在我的主文件中我几乎有......:

    int start_s = clock();
    size_t sizeOfData = 2032221073;
    boost::shared_ptr<BYTE> buffer((BYTE*) malloc(sizeOfData));
    readDataInParallel(buffer.get(), "/home/zahari/Desktop/kernels_big.dat", sizeOfData, 4);
    clock_t stop_s = clock();
    printf("%f %f\n", ((double) start_s / (CLOCKS_PER_SEC)) * 1000, (stop_s / double(CLOCKS_PER_SEC)) * 1000);

令人惊讶的是,从SSD读取时,与HDD相比,我没有获得任何加速?为什么会这样?

4 个答案:

答案 0 :(得分:4)

您的文件可能会被缓存,因此您测量的是CPU开销而不是I / O.您可以在使用“wontneed”标志读取文件之前调用文件posix_fadvise(),而不是刷新整个磁盘缓存,以建议内核不要缓存它。也就是说,假设您使用的是某种* nix平台或Mac OS。

答案 1 :(得分:2)

您的测量由所有设置四个线程的设备主导,每个线程执行一次读取,然后在四个线程中的最后一个执行barier.wait()时终止。

为了测量性能,每个线程应该在终止之前在循环中进行数千个单字节读取。

以下是我对改变的建议:

   void readFunctor(std::string pathToFile, size_t filePos, BYTE* buffer, size_t buffPos, size_t dataLn) 
   {

       FILE* pFile;
       pFile = fopen(pathToFile.c_str(), "rb");

       fseek(pFile, filePos, SEEK_SET);
       // initialize random number generation
       std::random_device rd;
       tr1::uniform_int_distribution<> randomizer(0, dataLn-1);

       for (int i=0; i<dataLn; i++)
       {
           fseek(pFile, filePos+randomizer(rd), SEEK_SET);
           fread(buffer++, sizeof(BYTE), 1, pFile);
       }

       fclose(pFile);
    }

答案 2 :(得分:2)

根据您的数据大小,在SSD或HDD中,操作系统将缓存您的文件。所以,可能你并没有真正访问你的磁盘,而是内存。

答案 3 :(得分:2)

可能的解释是您没有在SATA III设置下运行。您使用的SATA III 6gb / s SSD驱动器连接到主板上较旧的SATA II 3gb / s控制器。在这种情况下,您的SSD会被限制在3 gb / s。

检查您的硬件配置。如果它是SATA II,您需要更换主板以让您的SSD达到其全部性能潜力。

检查您的HDD磁盘驱动器,看它是SATA,SATA II还是SATA III。

确保在硬件接口级别比较苹果和苹果。