【发布时间】:2013-07-14 14:47:37
【问题描述】:
我的一些关于并行 I/O 的测试发生了一个非常奇怪的情况。情况就是这样。我有多个线程打开同一个文件的文件处理程序,并从文件的多个位置(均匀间隔)读取有限数量的字节并将其转储到数组中。一切都是通过增强线程完成的。现在,我假设由于随机访问搜索,HDD 应该会变慢。这就是为什么我的测试实际上是针对 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 相比,我没有得到任何加速?为什么会这样?
【问题讨论】:
-
它可能首先写入输出缓冲区?你的意思是 ?为什么它会写入输出缓冲区,即使它确实如此,这又有什么关系呢?
-
考虑限制因素——硬盘上的文件有多碎片化?随机部分会在同一个(或附近)圆柱体上吗?峰值吞吐量是多少(与 SATA 连接的容量相比)?还有什么在使用磁盘?
-
所有操作系统在内存中缓存文件。如果您多次运行测试,您将从内存而不是 HDD 或 SSD 中获取文件。
-
您使用什么大小的数据文件? 1 KB、1 MB、1 GB?
-
多个线程不能同时访问同一个驱动器。线程会争夺共享资源,这将成为主要的瓶颈。尝试将磁盘访问与互斥锁同步以获得更干净的基准。
标签: c++ c io parallel-processing solid-state-drive