Nano Hash - криптовалюты, майнинг, программирование

Параллелизм и оптимизация с использованием OpenMP

Я изучаю OpenMP. Для этого я пытаюсь сделать существующий код параллельным. Но мне кажется, что когда я использую OpenMP, мне становится хуже, чем когда я этого не делаю.

Мой внутренний цикл:

    #pragma omp parallel for
    for(unsigned long j = 0; j < c_numberOfElements; ++j)
    {
        //int th_id = omp_get_thread_num();
        //printf("thread %d, j = %d\n", th_id, (int)j);

        Point3D current;
        #pragma omp critical
        {
            current = _points[j];
        }

        Point3D next = getNext(current);

        if (!hasConstraint(next))
        {
            continue;
        }

        #pragma omp critical
        {
            _points[j] = next;
        }
    }

_points — это pointMap_t, определяемый как:

typedef boost::unordered_map<unsigned long, Point3D> pointMap_t;

Без OpenMP мое время работы составляет 44,904 с. С включенным OpenMP на компьютере с двумя ядрами это 64,224 с. Что я делаю неправильно?

01.10.2010

Ответы:


1

Почему вы заключили операции чтения и записи в _points[j] в критических разделах? Я не большой программист на C++, но мне кажется, что вам вообще не нужны эти разделы. Как вы написали (неназванные критические разделы), каждый поток будет ждать, пока другой проходит через каждый из разделов. Это может легко замедлить работу программы.

01.10.2010
  • Он segfaults без этого. Я не думаю, что смогу изменить карту из двух разных потоков одновременно. 01.10.2010

  • 2

    Кажется возможным, что поиск и запись в _points в критических разделах снижают производительность при использовании OpenMP. В однопоточном режиме это не приведет к конфликту.

    Такое совместное использование начальных данных кажется контрпродуктивным в контексте параллельного программирования. Можете ли вы изменить структуру, чтобы избежать этих спорных моментов?

    01.10.2010
  • Есть другой способ сделать это? Я не привык к параллельному программированию. 01.10.2010
  • @Vitor - я не понимаю, почему это будет ошибкой, если вы просто удалите критические разделы. Может быть, что-то в коде мы не видим? _points не добавляется и не удаляется во время выполнения цикла, верно? Имеют ли вызовы функций побочные эффекты за пределами текущей записи? Где исключение? 01.10.2010
  • Даже если вы удалите критические разделы, это все равно может привести к значительному замедлению работы. См., например. drdobbs.com/go-parallel/ статья/. 01.10.2010
  • @Steve Townsend From gdb: [Новая тема 0x7ffff0ccd710 (LWP 13329)] *** Обнаружен glibc *** /home/vitorpy/openmp/test: двойное освобождение или повреждение (fasttop): 0x00000000027f8be0 ***. bt показывает, что это происходит в операторе unordered_map[]. Вызовы функций не имеют побочных эффектов. 01.10.2010
  • @ Оли Чарльзворт, я посмотрю на это. Спасибо. 01.10.2010
  • @Vitor - неожиданный побочный эффект unordered_map::operator[]? Здесь может быть перетасовка вещей в базовой структуре. Можете ли вы использовать vector<Point3D>, так как вы просто зацикливаетесь с 0..size-1? 01.10.2010
  • @Steve Townsend Он по-прежнему дает сбои в _points[j] = next; линия. 01.10.2010
  • @Vitor - я не понимаю. У меня дома нет OpenMP, поэтому я даже не могу попробовать, если у вас есть полный код. 01.10.2010

  • 3

    Вам нужно показать остальную часть кода. Из комментария к другому ответу кажется, что вы используете карту. Это действительно плохая идея, особенно если вы сопоставляете числа 0..n со значениями: почему бы вам не использовать массив?

    Если вам действительно нужно использовать контейнеры, рассмотрите возможность использования контейнеров из библиотеки Intel Thread Building Blocks.

    01.10.2010
  • Ты прав. Карта в основном является пережитком старого дизайна, где идентификаторы не всегда были последовательными. Я превратил его в массив. Это все еще медленно, но я думаю, что, вероятно, столкнулся с проблемой ложного обмена или что-то в этом роде. 01.10.2010
  • @Vitto Py: попробуйте создать небольшой пример компилируемого кода, показывающий проблему. Вы настолько упростили код, что абстрагировались от проблемы. Одна вещь, которую можно попробовать, — это сделать hasContraint статическим встроенным, чтобы избежать штрафа за вызов функции. 02.10.2010

  • 4

    Я согласен, что было бы лучше увидеть какой-нибудь рабочий код.

    Конечная проблема здесь заключается в том, что в параллельном регионе есть критические элементы, а критические элементы (а) чрезвычайно дороги сами по себе и (б) по определению убивают параллелизм. Присвоение текущему определенному не обязательно должно быть внутри критического, поскольку оно является частным; Я бы не подумал, что назначение _points[j] тоже будет, но я не знаю, что делает эта штука с картой, так что вот так.

    Но у вас есть цикл, в котором у вас есть огромное количество накладных расходов, которые линейно растут в количестве потоков (двух критических областей), чтобы выполнить крошечный объем фактической работы (похоже, пройтись по связанному списку) . Это никогда не будет хорошей сделкой...

    01.10.2010
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..