фред медленной производительности в потоках OpenMP - PullRequest
2 голосов
/ 14 ноября 2011

Я использую Intel Xeon x2 (24 ядра) и Windows Server 2008.
Попытка распараллелить мою программу на C ++. Код шаблона здесь:

vector< string > files;
vector< vector< float > > data; 
...
data.resize( files.size() ); 

#pragma omp parallel for 
for (int i=0; i<files.size(); i++) { // Files count is about 3000
    FILE *f = fopen(files[i].c_str(), "rb"); 

    // every file is about 40 mb
    data[i].resize(someSize);
    fread(&data[i][0], sizeof(float), someSize, f); 

    fclose(f);
    ...
    performCalculations();  
}

Загрузка ЦП составляет всего от 0 до 5%.
Когда я вставляю вместо fread (& data [i] [0], sizeof (float), someSize, f) :

for (int j=0; j<data.size(); j++) {
    data[i][j] = rand(); 
}

Загрузка ЦП увеличивается до 100%.
Я уже пытался использовать fstream и WinApi ReadFile, но это не дало большого эффекта.

Что я делаю не так? Я не верю, что чтение с диска может быть таким медленным ...

Ответы [ 3 ]

6 голосов
/ 14 ноября 2011

Я не верю, что чтение с диска может быть таким медленным ...

Тогда тебе лучше начать верить. Диски невероятно медленные по сравнению с процессорами. Параллельный ввод-вывод обычно помогает только при чтении из нескольких источников, таких как отдельные диски или сетевые подключения. Это может хорошо решить проблемы с задержкой, но не проблемы с пропускной способностью.

Попытка чтения всех ваших данных за один раз, последовательно, а затем обработка их в параллельном цикле.

3 голосов
/ 14 ноября 2011

Показания диска нельзя распараллелить *: если у вас 1 или 24 ядра ЦП, это не изменит пропускную способность дискового ввода-вывода.

Если один performCalculations(); вызов быстрее, чем чтение содержимого одного ваших 40 МБ файлов, то нет необходимости распараллеливаться на нескольких процессорах. Выполнение вашей программы ограничено пропускной способностью вашего диска. Вы измерили это?

*: могут, но требуют аппаратного обеспечения. Точно так же, как распараллеливание выполнения на нескольких ЦП требует реального оборудования с несколькими ЦП, так как распараллеливание дискового ввода-вывода требует большего количества дискового ввода-вывода.

1 голос
/ 14 ноября 2011

Если вы используете обычный жесткий диск, никаких видимых ускорений не будет, потому что будет много одновременных чтений файлов.Жесткий диск в основном не может справиться с таким текущим чтением файла.Вот почему у вас только 0-5% загрузки ЦП, что означает, что большинство параллельных циклов просто ждут файловых операций.(Обратите внимание, что показания диска можно распараллелить, если на разных физических дисках или дисках есть несколько чтений файлов.)

Существует несколько решений:

  1. Попробуйте использовать SSDэто может поддерживать гораздо лучший случайный / параллельный доступ.
  2. Хотя все не так просто объяснить в этом ответе, попробуйте использовать конвейерный параллелизм .OpenMP не подходит для конвейеризации, но TBB поддерживает простой в использовании шаблон конвейера.Конвейер позволяет шаг чтения файла и другие этапы расчета, чтобы вы могли получить приличное ускорение.Конечно, должно быть достаточно вычислений.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...