ifort не распараллеливает код

Почему ifort не распараллеливает этот код? Постоянно пишет "цикл не распараллелен: наличие параллельной зависимости". Не могу понять, где зависимость. gfortran будет генерировать параллельный код, но скорость не очень высока.

PROGRAM erat
IMPLICIT NONE

INTEGER*8 :: i, rm, sn=1000000000
LOGICAL*1 , ALLOCATABLE, DIMENSION(:) :: nums

rm = INT( DBLE(sn)**0.5) + 1

ALLOCATE(nums(sn))
nums = .TRUE.                       !This line not parallelized

PRINT *, 'Doing initial sieve...'
nums(1) = .FALSE.
DO i = 2,rm
    nums(i**2:sn:i) = .FALSE.       !This line not parallelized
END DO
END PROGRAM erat

person chew socks    schedule 17.12.2012    source источник
comment
Несмотря на то, что вы не можете распараллелить это таким образом, вы все равно можете выполнять маскированное присваивание как forall(j = i**2:sn:i, nums(j)) nums(j) = .FALSE. или do concurrent. Это должно быть немного быстрее, так как после каждого шага внешнего цикла нужно пройти меньший набор индексов.   -  person sigma    schedule 18.12.2012
comment
Спасибо, это войдет в основной цикл do?   -  person chew socks    schedule 19.12.2012
comment
Действительно, вместо nums(i**2:sn:i) = .FALSE..   -  person sigma    schedule 19.12.2012


Ответы (1)


Об этой диагностике сообщается в операторе DO. Как один конкретный пример:

  • Когда i равно 2, цикл устанавливает num(8) в false.

  • Когда i равно 4, цикл также устанавливает num(8) в false.

Это две разные итерации цикла записи в одну и ту же ячейку памяти.

(Соответствующие форумы Intel — лучшее место для вопросов, которые могут касаться особенностей поведения их компиляторов.)

person IanH    schedule 17.12.2012
comment
Поскольку они оба записывают одно и то же значение и не читают значение, не будет ли параллелизм проблемой? - person chew socks; 17.12.2012
comment
Я подозреваю (я не знаю), что это касается соображений/уровней детализации, выходящих за рамки того, с чем имеет дело анализатор зависимостей. (Точно так же можно утверждать, что все, что нужно было сделать компилятору, — это выдать код, связанный с оператором печати, поскольку это единственный видимый эффект, который имеет ваш пример, но этот анализ тоже выходит за его рамки.) - person IanH; 17.12.2012
comment
Многократная одновременная запись в одно и то же место — даже с одним и тем же значением — приводит к неопределенному поведению, и компилятор прав, избегая этого. - person Jonathan Dursi; 17.12.2012