0

В настоящее время я работаю над системой, в которой я читаю файл размером более 200 миллионов записей (строк), поэтому я подумал, что могу улучшить модель производителя и потребителя (работая, как я читал). Тем не менее, я не добился высокой производительности, и я обеспокоен тем, что мой общий дизайн ошибочен. Для того, чтобы поместить его в контекст:C++ Параллельный файл ввода-вывода и анализ с задачами OpenMP

int i = 0; 
string buffer[MAX_SIZE]; 

//critical regions exist for map_a and map_b (shared below) in the task function 

#pragma omp parallel shared(map_a), shared(map_b), num_threads(X) 
#pragma omp single 
{ 
    while (getline(fin, line) && !fin.eof()) 
    { 
     buffer[i] = line; 
     if (++i == MAX_SIZE) 
     { 
#pragma omp task firstprivate(buffer) 
      work_on_data(buffer, map_a, map_b); 
      i = 0; 
     } 
    } 
} 

Каждая запись в буфере занимает примерно 49-95μ обрабатывать в work_on_data, с дисперсией из-за условными, и я подозреваю, что pragma omp critical регионы (по одному для каждой общей карты). Для двух критических областей:

  1. Для map_a: если определенный регистр соответствует записи, запись должна быть добавлена ​​на карту с ключом, полученным из записи. Если запись уже существует, ее необходимо будет обновить. Существует критическая область над чтением карты, потенциальным обновлением и записью.
  2. Для map_b: для каждой записи карта должна быть обновлена. Критическая область охватывает те же действия, что и (1), то есть чтение, потенциальное обновление/вставка и запись.

Итак, в отношении моего подхода. Должен ли я использовать отдельный pthread для буферизации ввода-вывода? Должен ли я просто буферизировать в один огромный буфер, выделенный памятью, и создавать задачи, которые pragma omp parallel for над подмножеством его записей? Я не испытываю такого программирования.

Заранее благодарен!


Edit: Уточнено использование критической области.

+0

Можете ли вы дать более подробную информацию о картах и ​​о том, как они используются? Вы можете удалить критические регионы. – ElderBug

+0

@ ElderBug Я немного разъяснил выше, и я могу добавить больше кода позже (на данный момент нажать на время).К сожалению, я не считаю, что критические регионы могут быть удалены, в каждой задаче нет уникальности записей, которые препятствуют чтению/обновлению/записи одних и тех же ключевых записей на обеих картах. Я пробовал использовать атомную запись, однако застрял со старой версией OpenMP. – PidgeyBAWK

ответ

2

О IO, я не думаю, что вы можете получить большую производительность, поскольку она уже должна быть прилично буферизована ОС. Вы всегда можете попытаться реализовать большую буферизацию самостоятельно (потенциально с производителем/потребителем) или использовать файл с отображением памяти, но я боюсь, что вы будете разочарованы приростом производительности (и getline намного проще).

Об анализе файлов вы должны, конечно же, попытаться оптимизировать вычисления, но есть потенциально намного лучший возможный выигрыш, если вы сможете удалить критические регионы. Обычно цель состоит в том, чтобы полностью удалить зависимость от общих объектов. Как вы это делаете, это зависит от вашего приложения, но общая идея состоит в том, чтобы иметь независимую обработку в каждом потоке, а затем объединить результаты вместе. В вашем случае вы можете выделять независимые карты в каждом потоке, а затем обновлять реальные карты. Если вам нужны исходные карты для обработки, прочитайте их, но не обновляйте/не записывайте их, не записывайте независимые объекты и не обновляйте их позже. Таким образом, вы можете удалить критические области (операции чтения являются потокобезопасными).

В качестве побочного примечания, это очень специфическое приложение, а также конкретное оборудование. Если время обработки короче по сравнению с чтением файла (что может сильно зависеть от вашего CPU/HDD/SSD), вы можете получить большую производительность с лучшей буферизацией ввода-вывода, и это может даже сделать многопоточность бесполезной. Кроме того, если слияние результатов слишком тяжелое, разделение результатов может не стоить того. Важно, чтобы вы разделили/объединили результаты; вы можете просто создать список обновлений или создать фактическую карту, которую вы объедините. Возможно также, что критические регионы не являются проблематичными. Попробуйте поэкспериментировать, чтобы узнать, что лучше для вас.

+0

Вы, безусловно, были правы, чтобы просто изучить критические регионы. Первый был крупным болотом, и я получил значительное ускорение. Теперь у меня есть проблема эффективного слияния данных ... Я вернусь к вам с результатами! – PidgeyBAWK

+0

Я принял ваш совет и работал над объединением данных. К сожалению, у меня возникли проблемы с извлечением данных из каждой задачи pragma omp, как объяснялось по этому вопросу, я спросил http://stackoverflow.com/questions/27849876/c-openmp-tasks-passing-by-reference-issue – PidgeyBAWK

+0

@PidgeyBAWK Я прокомментировал другой вопрос – ElderBug

Смежные вопросы