Почему переменные цикла должны быть подписаны параллельно for?
Я просто изучаю OpenMP из онлайн-учебников и ресурсов. Я хочу квадратировать матрицу (умножить ее на себя), используя parallel for
петли. В документация компилятора IBM, я нашел требование, что "переменная цикла должна быть signed
целое число."Это также верно в реализации GCC? Это указано в в стандарт OpenMP? Если да, то есть ли основания для этого требования?
(это не имеет большого значения, поскольку ожидаемые размеры намного меньше, чем INT_MAX
, но это стоило мне некоторых отливок.)
4 ответов
согласно спецификации OpenMP 3.0:http://www.openmp.org/mp-documents/spec30.pdf, для переменной может иметь знаковый или беззнаковый целочисленный тип, см. 2.5.1 Loop Construct. Вопрос в том, соответствует ли данная реализация OpenMP этой последней спецификации.
цитирую почему не разрешены неподписанные переменные индекса OpenMP? :
по словам OpenMP 2.0 C / C++ В API спецификация (pdf), раздел 2.4.1, это одно из ограничений цикла for. Причины не приводятся. для этого, но я подозреваю, что это просто упростите предположения, что код и компилятор должен сделать, так как есть специальный код, чтобы гарантировать, что диапазон не переполняет максимум значение тип.
OpenMP 3.0, по-видимому, позволяет беззнаковые типы тоже, но я не видел он еще в действии.
короче говоря, это часть стандарта, и следующая версия позволит целые числа без знака.
вот возможная причина этого. The та же статья говорит, что
-
b, ub, incr
являются петлевыми инвариантными знаковыми целочисленными выражениями и -
exit_cond
примет вид:iv <= ub
илиiv < ub
илиiv >= ub
илиiv > ub
(гдеiv
является переменной итерации, о которой вы спрашиваете)
С exit_cond
условие включает сравнение, и сравнение выполняется против подписанного ub
переменная переменная цикла iv
есть быть подписанным, чтобы избежать возможных проблем с подписанным/неподписанным сравнением.
чтобы ответить на ваш первый вопрос о gcc
. Нет, кажется, что gcc
легко принимает unsigned
или size_t
переменные цикла в чем-то вроде
#pragma omp parallel for
for (size_t i = 0; i < N; ++i) {
/* do it */
}
по крайней мере, мой (gcc v 4.4 на 64-битном ubuntu) не жалуется и делает правильно.