Реентерабельность и STL
От: _hum_ Беларусь  
Дата: 25.04.18 15:56
Оценка:
Хотелось бы узнать, как на данный момент обстоит дело с гарантиями правомерности использования функций STL в параллельном программировании. Например, насколько я могу рассчитывать, что тот же распараллеленный средствами OpenMPI цикл наподобие
const long nSize = 100000;

std::vector<float> v(nSize);

#pragma omp parallel for
for (long i = 0; i < nSize; ++i)
  v[i] = sqrt(i);

будет корректно работать (оператор доступа к элементу вектора реентерабельный)?

Из того, что попалось на глаза — на stackoverflow:

The standard says:
Except where explicitly specified in this standard, it is implementation-defined which functions in the Standard C++ library may be recursively reentered.

И там же дальше проводятся рассуждения, что такой подход довольно ограничительный, и что намного разумнее:

The standard should mandate that all standard functions must be reentrant, unless otherwise specified.

I would

completely ignore the possibility of of any standard function being non-reentrant, except when it is clear that the function cannot be reasonably made reentrant.


В связи с чем вопрос — может, уже ввели какое-нибудь понятие наподобие "внутренне/изначально реинтерабельный", означающее, что функция реинтерабельна, если только нет возможности привнести нарушение реинтерабельности извне (через аргументы функции, шаблоны типов)?

Если же нет, как в таком случае работать с STL в OpenMPI — полностью переводить на указатели?
Re: Реентерабельность и STL
От: watchmaker  
Дата: 25.04.18 16:23
Оценка: +4
Здравствуйте, _hum_, Вы писали:

__> цикл наподобие будет корректно работать

Да, такой цикл будет корректно работать.


Но почему в тексте написано OpenMPI, а в коде используется OpenMP? Это же разные технологии.

И почему в тексте пишешь про реентабленость, а в коде — про параллельный доступ к одному контейнеру. Это тоже разные вещи: Reentrancy

This definition of reentrancy differs from that of thread-safety in multi-threaded environments. A reentrant subroutine can achieve thread-safety, but being reentrant alone might not be sufficient to be thread-safe in all situations. Conversely, thread-safe code does not necessarily have to be reentrant (see below for examples).


Короче, тут в сообщении смешаны четыре разных сущности, и как можно серьёзно отвечать на такой вопрос просто непонятно
Отредактировано 25.04.2018 16:25 watchmaker . Предыдущая версия . Еще …
Отредактировано 25.04.2018 16:24 watchmaker . Предыдущая версия .
Re[2]: Реентерабельность и STL
От: _hum_ Беларусь  
Дата: 25.04.18 19:12
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, _hum_, Вы писали:


__>> цикл наподобие будет корректно работать

W>Да, такой цикл будет корректно работать.

почему?


W>Но почему в тексте написано OpenMPI, а в коде используется OpenMP? Это же разные технологии.


точно, спасибо. я как-то раньше думал, что есть технология mpi для межпроцессного взаимодействия и openmpi — для многопоточного распараллеливания, и что отличаются названия по присутствию префикса open, а не по отсутствию I в конце

W>И почему в тексте пишешь про реентабленость, а в коде — про параллельный доступ к одному контейнеру. Это тоже разные вещи: Reentrancy

This definition of reentrancy differs from that of thread-safety in multi-threaded environments. A reentrant subroutine can achieve thread-safety, but being reentrant alone might not be sufficient to be thread-safe in all situations. Conversely, thread-safe code does not necessarily have to be reentrant (see below for examples).


потому что я ориентировался на следующее понимание реентерабельности:
Wiki/Реентерабельность

Компьютерная программа в целом или её отдельная процедура называется реентера́бельной (от англ. reentrant — повторно входимый), если она разработана таким образом, что одна и та же копия инструкций программы в памяти может быть совместно использована несколькими пользователями или процессами. При этом второй пользователь может вызвать реентерабельный код до того, как с ним завершит работу первый пользователь и это как минимум не должно привести к ошибке, а при корректной реализации не должно вызвать потери вычислений (то есть не должно появиться необходимости выполнять уже выполненные фрагменты кода).

Этот вариант отличается от англоязычного тем, что требуется корректная работа не только самой функци, но целой программы, в которой она вызывается.
Так вот в таком понимании мне для корректности отработки цикла достаточно было бы просто гарантии реентерабельности соответствующих функций вектора.
Re[3]: Реентерабельность и STL
От: watchmaker  
Дата: 25.04.18 19:51
Оценка:
Здравствуйте, _hum_, Вы писали:

__>>> цикл наподобие будет корректно работать

W>>Да, такой цикл будет корректно работать.
__>почему?
Потому что сказано

[container.requirements.dataraces]

1 For purposes of avoiding data races (20.5.5.9), implementations shall consider the following functions to be
const: begin, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at
and, except in associative or unordered associative containers, operator[].
2 Notwithstanding 20.5.5.9, implementations are required to avoid data races when the contents of the contained
object in different elements in the same container, excepting vector<bool>, are modified concurrently.

И это не имеет отношения к реентабельности.

__>потому что я ориентировался на следующее понимание реентерабельности:

__>Так вот в таком понимании мне
Если будешь наделять более-менее устоявшийся термин каким-то новым "своим пониманием", то тебя скорее-всего просто не поймут. Не советую так делать :)
Лучше прочитать и сравнить определения в других источника, чтобы вольности формулировок и нестрогости интерпретаций не приводили не к извращению термина.
Ну а те же примерны в википедии отлично показывают, что свойства реентабельности и конкурентности могут встречаться во всех комбинациях. То есть это независимые свойства, а не одно выводится из другого.
Отредактировано 25.04.2018 20:08 watchmaker . Предыдущая версия . Еще …
Отредактировано 25.04.2018 19:58 watchmaker . Предыдущая версия .
Re[4]: Реентерабельность и STL
От: _hum_ Беларусь  
Дата: 25.04.18 20:24
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, _hum_, Вы писали:


__>>>> цикл наподобие будет корректно работать

W>>>Да, такой цикл будет корректно работать.
__>>почему?
W>Потому что сказано
W>

W>[container.requirements.dataraces]

W>1 For purposes of avoiding data races (20.5.5.9), implementations shall consider the following functions to be
W>const: begin, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at
W>and, except in associative or unordered associative containers, operator[].
W>2 Notwithstanding 20.5.5.9, implementations are required to avoid data races when the contents of the contained
W>object in different elements in the same container, excepting vector<bool>, are modified concurrently.

о. спасибо.

__>>потому что я ориентировался на следующее понимание реентерабельности:

__>>Так вот в таком понимании мне
W>Если будешь наделять более-менее устоявшийся термин каким-то новым "своим пониманием", то тебя скорее-всего просто не поймут. Не советую так делать.

Кхм.. дело в том, что не совсем понятно, что такое устоявшийся (есть какой-то аналог БСЭ для computer science?). Я открыл сперва русскую Вики. Там черным по белому написано, то, что я привел выше, и при этом еще и сказано

Реентерабельность тесно связана с безопасностью функции в многопоточной среде (thread-safety), тем не менее, это разные понятия (в практическом программировании под современные ОС термин «реентерабельный» на деле равносилен термину «thread-safe»).


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


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


а я нигде не утверждал, что они равносильны. Я лишь говорил, что мне достаточно было реентерабельности (в "моем понимании").

п.с. Странно все-таки, что нет отдельного понятия для функции, которая при параллельном исполнении [безо всяких средств синхронизации] не может привести к нарушению логики исполнения всей программы. Обычно в таких случаях в математике вводят что-то наподобие "реентерабельность в узком/широком смысле".

upd. Кстати, забавно. В ссылках в ангаязычной статье про реентерабельность:
Kerrisk 2010, p. 657.

Alghtought the use of critical sections to implement thread safety is a significiant improvement over the use of pre-function mutexes, it is still somewhat inefficient because there is a cost to locking and unlocking a mutex. A reinterant function achieves thread safety without the use of mutexes. It does this by avoiding the use of global and static variables. Any information that must be returned to the caller or maintained between calls to the fucntion, is stored in buffer allocated by caller


Chen, Raymond (June 29, 2004). "The Difference Between Thread-safety and Re-entrancy". The Old New Thing. Microsoft Developer Network. Archived from the original on April 24, 2018. Retrieved April 24, 2018.

An operation is "thread-safe" if it can be performed from multiple threads safely, even if the calls happen simultaneously on multiple threads.

An operation is re-entrant if it can be performed while the operation is already in progress (perhaps in another context). This is a stronger concept than thread-safety, because the second attempt to perform the operation can even come from within the same thread.

Это как бы противоречит написанному в англоязычной вики (и соответствует написанному в русскоязычной ).
Отредактировано 25.04.2018 20:47 _hum_ . Предыдущая версия . Еще …
Отредактировано 25.04.2018 20:44 _hum_ . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.