Есть ли возможность получить прирост производительности на fstream (чтение файлов) с помощью openMP - PullRequest
3 голосов
/ 16 февраля 2012

Я хотел бы знать, может ли быть какое-либо увеличение производительности при чтении файла с использованием openMP.

Пример кода,

fstream file;

file.open("test.txt",ios::in);

file.seekg(0,ios::end);

int len = file.tellg();

char *arr = new char[len];

char *temp = new char[1];

int i;

#pragma omp parallel for shared(arr, len) private(temp, i)
for(i = 0; i < len; i++)
{
    file.seekg(i);
    file.read(temp,1);
    arr[i] = temp[0];
}

Полагаю, использование нескольких потоков для операции ввода-вывода - плохая опция, потому что, наконец, операция чтения файла будет сериализована. Но все же я хотел бы узнать, можно ли ожидать прироста производительности. Кроме того, я также хотел бы знать, как openMP обрабатывает параллельные операции чтения файлов.

Ответы [ 2 ]

7 голосов
/ 16 февраля 2012

Как вы упомянули, вы вряд ли сможете ускорить распараллеливание какой-либо задачи, связанной с вводом / выводом, подобной этой. Тем не менее, есть гораздо большая проблема. Код даже не правильный.

Методы seekg() и read() изменяют переменную file. Таким образом, ваши итерации не являются независимыми. Таким образом, вы будете иметь условия гонки в потоке. Другими словами, цикл не распараллелен.

Так что не ожидайте, что этот код будет работать вообще - не говоря уже о лучшей производительности.

3 голосов
/ 16 февраля 2012

Хотя есть много улучшений производительности в файловых потоках, которые вы предлагаете, среди них нет:

  • std::streambuf с состоянием и попытка одновременного доступа к нему из нескольких потоков выполнения приведет к полной путаницеit up.
  • Обработка отдельных символов, по сути, является наихудшим сценарием для современного процессора.Если вы действительно сделаете это параллельно, у вас будет несколько процессоров, работающих с одинаковыми строками кэша.Это на самом деле значительно ухудшит производительность по сравнению с одним потоком выполнения.
  • Я не знаю, почему люди так любят использовать запросы: каждый поиск по существу убивает любой текущий буфер и может вызвать системный вызов простопозиционировать поток в определенном состоянии.Ключевая проблема с поиском заключается в том, что поток устанавливается либо для чтения, либо для записи, в зависимости от того, какая следующая операция.Да, режим открытия может быть принят во внимание, но, вероятно, это не так.

Если вы хотите прочитать быстрый подход к чтению файла, используя std::ifstream, вам следует

  • imbue() a std::locale, который объявляет не делать никаких преобразований
  • открыть файл в режиме std::binary
  • пропустить , пытаясь получить то, что может бытьнеправильная оценка размера файла (поиск до конца и надежда на то, что это как-то дает вам количество символов в файле, бесполезна)
  • считывание в подходящий std::ostream например std::ostringstream (если вы можете предоставить целевой буфер, вы можете использовать более быстрый поток вывода), используя оператор вывода для потоковых буферов: out << in.rdbuf()

    Я не вижу, чтобы параллелизм помог вам с чтением потока.

...