omp ordered для ввода/вывода убивает параллельность.

Serab

Идея такая: надо обработать несколько увесистых частей большого файла. Причем считывание одной части (порядка гига) в память занимает примерно равное с вычислениями время, поэтому решил, что элементарным улучшением будет добавление omp:

//...
ifstream inputStream;
// ...
#pragma omp parallel for ordered schedule(static,1) num_threads(2)
for( int i = 0; i < totalParts; ++i ) {
vector<int> data;
data.resize( partSize );

#pragma omp ordered
{
inputStream.read( reinterpret_cast<char*>( &data.front data.size * sizeof( int ) );
}

// Computation
}

Так вот оно, падла, все равно выполняет последовательно, т.е. второй тред не начинает выполнение ordered до того, как первый закончит итерацию целиком. Что я делаю не так?
За
1) префиксный инкремент,
2) тупую сериализацию,
3) использование тредов тут,
не гнобить плз, вопрос скорее по openmp, чем по async i/o :grin:

Serab

А теперь я еще и удалил всю прогу, ошибившись в маске :(

Serab

Блиа, стал уже думать, как замутить undelete при помощи dd + grep :grin:, но вспомнил, что настроил в виме backup'ы в отдельный каталожег. Фуф.

Maurog

Так вот оно, падла, все равно выполняет последовательно
а как вы планировали стрим (ifstream) читать параллельно? для этого надо файл в разных потоках открыть, поseek-аться в нужное место и читать параллельно
но про async io вы правильно подметили, что возможно, у вас прога просядет на многопоточном чтении вместо однопоточного
зы: в omp ничего не понимаю

Serab

ну смысл ordered в том, чтобы одновременно они и не читали как раз :) Т.е. первый тред прочитал, и как только начал считать, я хочу, чтобы второй уже начал читать, а так не происходит.
в omp ничего не понимаю
ну типа оно и видно по предыдущему посту :grin:

aoand

Параллельно читать fstream не надо; последовательное чтение даёт скорость, близкую к скорости последовательного доступа к диску, т.е., максимум, который может выдавать диск в установившемся режиме. Попытка параллельного чтения заставит диск делать много seek'ов (если это только не SSD что убьет производительность.
Как я понял, топикстартер хочет, чтобы чтение было последовательным, но обработка шла параллельно с чтением. В его случае (обработка занимает примерно столько же времени, сколько и чтение данных) это может оказаться очень полезным.
Т.е., вопрос состоит в том, как средствами OpenMP реализовать producer/consumer. Гугл говорит, что OpenMP не очень-то заточен на такой сценарий и что, если всё же хочется его использовать, то надо смотреть в сторону OpenMP dependency graph.

Serab

Т.е., вопрос состоит в том, как средствами OpenMP реализовать producer/consumer. Гугл говорит, что OpenMP не очень-то заточен на такой сценарий и что, если всё же хочется его использовать, то надо смотреть в сторону OpenMP dependency graph.
Мне даже не нужен producer/consumer в широком смысле, так как эти части, которыми я считываю, они логически связаны, т.е. надо считывать их целиком в память для обработки. Т.е. надо именно пока один читает с диска, считать другую часть. И вопрос тут именно про openMP и указанную семантику ordered (судя по описанию должно быть как я хочу, но тесты четко показывают обратно: пробовал и printf'ы вставлять, и запускать top и iotop и смотреть: четко, 20 секунд считывает, 20 — 100% загрузка проца, а IO на нуле и т.д.).
А если бы мне это захотелось сверхэффективно написать, полез бы почитал как раз соседний тред.

aoand

Я, как и предыдущий оратор, в OpenMP не разбираюсь, но всё же попробую посоветовать :grin: . Если ты пишешь под Linux или NetBSD, то попробуй на свой файл сказать что-нибудь в духе

posix_fadvise(fd,0,0,POSIX_FADV_SEQUENTIAL|POSIX_FADV_NOREUSE|POSIX_FADV_DONTNEED);

Это заставит операционную систему делать упреждающее чтение из файла и по возможности не забивать кеш его содержимым. Из цикла обработки попробуй убрать распараллеливание и, возможно, уменьши partSize — это заставит программу чуть чаще вызывать чтение из файла и должно повлиять на мнение ОС о твоём паттерне обращения к файлу.

Marinavo_0507

Параллельно читать fstream не надо; последовательное чтение даёт скорость, близкую к скорости последовательного доступа к диску, т.е., максимум, который может выдавать диск в установившемся режиме. Попытка параллельного чтения заставит диск делать много seek'ов (если это только не SSD что убьет производительность.
Если raid1, то в два потока будет быстрее, и если raid0 то может быть тоже.

aoand

С raid'ами работать не доводилось, поэтому такой дурацкий вопрос — а разве raid не станет параллелить большой одиночный запрос на чтение идущих подряд данных?
Более того, в том же raid1 данные то будут лежать на дисках страйпами, поэтому автоматически получится, что при линейном чтении данные будут параллельно подгружаться с разных дисков.

Marinavo_0507

Более того, в том же raid1 данные то будут лежать на дисках страйпами, поэтому автоматически получится, что при линейном чтении данные будут параллельно подгружаться с разных дисков.
Страйпами - это raid0, raid1 - это зеркало.
Если страйпы достаточно малы, то однозначно будет ускоряться последовательное чтение, а от нескольких потоков будет замедление. Если велики, то тоже по идее будет, но не факт, что так же хорошо, как в несколько потоков - зависит от интеллектуальности планировщика в/в.
В raid1 чтение в два потока однозначно распараллелится, последовательное чтение в один поток - может быть тоже в теории, но на практике не так круто получается.

Serab

хм, похоже, что надо вботать реализацию omp в gcc, потому что с icc та же программа ведет себя идеально. Правда во время чтения проц грузит на 100%, неужели spinlock?
Оставить комментарий
Имя или ник:
Комментарий: