Предотвращение неиспользуемых предупреждений о переменных с помощью инструкций перед компилятором внутри параллельных блоков openmp - PullRequest
0 голосов
/ 05 апреля 2019

Фон

Моя проблема возникает из-за сочетания нескольких конкретных вещей.

  1. Я использую операторы препроцессора, чтобы определить, какие вычисления нужно включить в производимый исполняемый файл
  2. Я использую параллель openmp для блоков с default(none) (потому что я параноик).
  3. Код компилируется и работает правильно, но может выдавать предупреждения о неиспользуемых переменных в зависимости от флагов препроцессора. Технически это не ошибка, но я хотел бы удалить эти предупреждения (и нет, я имею в виду не просто отключение предупреждений компилятора, но фактически устранение причины, то есть неиспользуемых переменных).

По сути, у меня есть что-то вроде

#pragma omp parallel \
  default(none) \
  shared(...) \
  private(...)
  {
  #pragma omp for
  for (i = 0; i < num_i; ++i) {

    compute_stuff;

    #if FLAG_1
      compute_more_stuff;
    #endif
    }
  }

Основной выпуск

Предположим для ясности, что переменная x требуется, только если FLAG_1 равен true. Я мог бы обернуть объявление для x и его использование в операторах #if FLAG1 ... #endif, но мне все еще нужно перечислить x в списке переменных для #pragma omp parallel, и, насколько я знаю, я могу ' Вложите #if FLAG1 ... #endif в оператор #pragma omp parallel (длина строки - много переменных). Итак, я либо получаю ошибки о перечислении несуществующих переменных в прагме omp, либо предупреждения о неиспользуемой переменной.

Возможные (но неудовлетворительные) решения

  1. В этом случае все удаленные переменные являются omp-private, и я заранее признаю, что простая замена default(none) на default(private) решит проблему. Тем не менее, мне нравится практика кодирования default(none), и я хотел бы сохранить ее, если это возможно.

  2. Другой вариант - просто разбить omp-параллель на что-то вроде следующего, но compute_stuff и compute_more_stuff имеют некоторые общие вычисления / доступ к памяти, которые я бы хотел избежать дублирования.

#pragma omp parallel \
  default(none) \
  shared(...) \
  private(...)
  {
    #pragma omp for
    for (i = 0; i < num_i; ++i) {
      compute_stuff;
    }
  }

#if FLAG_1
#pragma omp parallel \
  default(none) \
  shared(...) \
  private(...)
  {
    #pragma omp for
    for (i = 0; i < num_i; ++i) {
      compute_more_stuff;
    }
  }
#endif

Будем весьма благодарны за любые мысли о том, как поддерживать хорошие методы кодирования, сохраняя читабельный и эффективный код!

1 Ответ

1 голос
/ 05 апреля 2019

Если вы используете C ++ 17, как насчет атрибута [[maybe_unused]]?:

#pragma omp parallel \
  default(none) \
  shared(...) \
  private(...)
  [[maybe_unused]] variable_potencially_not_used;
  {
  #pragma omp for
  for (i = 0; i < num_i; ++i) {

    compute_stuff;

    #if FLAG_1
      variable_potencially_not_used = 1;
    #endif
    }
  }

Если нет, то альтернативой является реализация чего-то похожего на Q_UNUSED макрос.Вы можете заявить о себе:

#define MAYBE_UNUSED(X) (void)X
#pragma omp parallel \
  default(none) \
  shared(...) \
  private(...)
  MAYBE_UNUSED(variable_potencially_not_used);
  {
  #pragma omp for
  for (i = 0; i < num_i; ++i) {

    compute_stuff;

    #if FLAG_1
      variable_potencially_not_used = 1;
    #endif
    }
  }```
...