У меня очень странная ситуация с некоторыми из моих тестов, касающихся ввода / вывода паралелла. Вот ситуация … У меня есть несколько потоков, открывающих обработчик файла для одного и того же файла и считывающих из нескольких мест файла (равномерно распределенных интервалов) конечное число байтов и выгружающих его в массив. Все сделано с форсированными потоками. Теперь я предполагаю, что с жестким диском должно быть медленнее из-за поиска произвольного доступа. Вот почему мои тесты нацелены на SSD. Оказывается, я почти не получаю никакого ускорения при чтении того же файла с твердотельного диска по сравнению с жестким диском. Интересно, в чем может быть проблема? Мне это кажется очень удивительным / я также публикую свой код ниже, чтобы увидеть, что именно я делаю:
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? Почему это может быть?
Ваш файл, вероятно, кэшируется, поэтому вы измеряете нагрузку на процессор, а не на ввод-вывод. Вместо очистки всего дискового кэша вы можете вызвать posix_fadvise()
перед чтением файла с флагом «wontneed», чтобы ядро не кэшировало его. То есть, если вы на какой-то платформе * nix или Mac OS.
В зависимости от вашего размера данных, на SSD или HDD, ОС будет кэшировать ваш файл. Так что, вероятно, вы обращаетесь не к своим дискам, а к памяти.
В ваших измерениях преобладает совокупность настроек четырех потоков, каждый из которых выполняет одно чтение, а затем завершается, когда последний из четырех потоков выполняет 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);
}
Возможным объяснением этого является то, что вы не работаете под настройкой SATA III. Используемый SSD-накопитель SATA III 6 Гбит / с подключен к более старому контроллеру SATA II 3 Гбит / с на материнской плате. В этом случае ваш SSD сокращается до 3 Гбит / с.
Проверьте конфигурацию вашего оборудования. Если это SATA II, вам нужно заменить mobo, чтобы ваш SSD полностью раскрыл свой потенциал производительности.
Проверьте также жесткий диск и убедитесь, что это SATA, SATA II или SATA III.
Убедитесь, что вы сравниваете яблоки с яблоками на уровне аппаратного интерфейса.