Почему при использовании флага компилятора MPI_Bcast и -O3 появляется ошибка разбиения стека, но все работает без -O3? - PullRequest
1 голос
/ 29 мая 2020

Я новичок в MPI, поэтому извиняюсь, если это просто.

У меня есть код из месяца или двух go, который работал нормально, но я решил go вернуться и отредактируйте его. (Он был написан, когда я только начинал, и это не критичный для производительности раздел.) Код в основном генерирует случайный график для одного процесса, а затем делится результатами со всеми другими процессами. Ниже приводится отрывок из версии «Первые шаги ребенка»: правильный способ:

if (commrank == 0) {
    graph = gengraph(params);
    MPI_Bcast(graph, n*n, MPI_UNSIGNED, 0, MPI_COMM_WORLD);
} else {
    graph = malloc(sizeof(unsigned int)*n*n);
    MPI_Bcast(graph, n*n, MPI_UNSIGNED, 0, MPI_COMM_WORLD);
}

Проблема в том, что я продолжаю получать при компиляции с оптимизацией -O3 ошибки "разбивания стека" во второй версии, хотя при неоптимизированной компиляции все работает нормально. Обратите внимание, что я несколько раз проверял функцию распределения графа и отлаживал ее, и, похоже, все в порядке. Я также отладил вторую версию, и она, похоже, работает нормально. Ошибка sh возникает позже, когда я пытаюсь освободить графическую память. (Обратите внимание, что это не ошибка двойного освобождения, и, опять же, она отлично работает в наивной реализации и имеет некоторое время.) if вместо использования переменной recvStatus я использую MPI_STATUS_IGNORE. И, опять же, это не работает только с -O3.

Любые мысли были бы очень признательны. Если это поможет, я использую mpi cc поверх g cc 7.5.0, но я полагаю, что делаю что-то глупое, вместо того, чтобы столкнуться с проблемой компилятора.

1 Ответ

1 голос
/ 30 мая 2020

Я изменил компилятор mpi cc на Clang и использовал Address Sanitizer по предложению @ hristo-iliev и обнаружил ошибку в последующем вызове MPI (recv с неправильным размером счетчика). Это привело к неопределенному поведению. Примечательно, что дезинфицирующее средство адреса довольно четко определило местонахождение ошибки, в то время как valgrind лишь дал довольно непрозрачные признаки того, что что-то происходит в MPI (как, впрочем, и всегда).

Приносим извинения сообществу StackOverflow за это , так как код выше не был виновником (что не совсем удивительно). Это было обычное поведение undefined из-за небрежности.

...