А ещё никогда не совершать ошибки и иметь чистую библиотеку для используемых сущностей (привет STL) ^_^
Ведь на недетерминированность компилятор T++ никак не среагирует. В отличии от Хаскела, т.к. это чистый язык.
Модератор: Модераторы разделов
А ещё никогда не совершать ошибки и иметь чистую библиотеку для используемых сущностей (привет STL) ^_^
Конкретно эти функции возвращают разные значения несмотря на то, что им передаются на вход одинаковые значения входных аргументов. Это называется недетерминированность.
При том что ООП -- это один большой побочный эффект.
А причём тут синхронизирующая переменная?
1. Назовите побочный эффект функции rand
Т.е. вы изначально были согласны, что Т++ будет ловить массу побочных эффектов?
И каким же боком она связана с побочными эффектами?
Тогда объясните принципиальную разницу между
Код: Выделить всё
tfun int fib (int n) {
return n < 2 ? n : fib(n-1) + fib(n-2);
}Код: Выделить всё
long fib_parallel(long n)
{
long x, y;
if (n < 2) return n;
#pragma omp task default(none) shared(x,n)
{
x = fib_parallel(n-1);
}
y = fib_parallel(n-2);
#pragma omp taskwait
return (x+y);
}Рассказывают, что когда в Афгане сбили советский миг, американцы были поражены не сколько совершенной аэродинамикой самолёта, а практически полным отсутсвием электроники. Это я тому, что мощность железа никак не говорит о качестве софта под него.
sciko писал(а): ↑10.04.2011 21:31Тогда объясните принципиальную разницу между
иКод: Выделить всё
tfun int fib (int n) { return n < 2 ? n : fib(n-1) + fib(n-2); }Код: Выделить всё
long fib_parallel(long n) { long x, y; if (n < 2) return n; #pragma omp task default(none) shared(x,n) { x = fib_parallel(n-1); } y = fib_parallel(n-2); #pragma omp taskwait return (x+y); }
Оба примера их манов.
исхожу из определения детерминированности алгоритма, детерминированности конечного автомата.
NickLion писал(а): ↑10.04.2011 22:53А вот насчёт детерминированности - тут проблема терминологии. Я, как видимо и Crazy, исхожу из определения детерминированности алгоритма, детерминированности конечного автомата.
(А в этих терминах текущий компьютер является детерминированным конечным автоматом, а потому не может реализовать недетерминированность. Ну, эмулировать можно, но не более.)
/dev/random писал(а): ↑10.04.2011 23:52В то же время, детерминированный _алгоритм_ может брать данные откуда угодно, и недетерминированным от этого не станет.
Классическая rand не меняет глобальных переменных и является примером недетерминированной функции без побочных эффектов.
Отсюда следует, что говорить о недетерминированности алгоритма нет смысла, т.к. он не реализуем. Поэтому логично говорить только о чистоте функции, а значит её детерминированости.
Затрудняюсь оценить как связаны состояние гонки и недетерминированность алгоритма.
Вообще-то фундаментально они идентичны.
('man rand') писал(а):EXAMPLE
POSIX.1-2001 gives the following example of an implementation of rand() and srand(), possibly useful when one needs the same
sequence on two different machines.
Код: Выделить всё
static unsigned long next = 1; /* RAND_MAX assumed to be 32767 */ int myrand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % 32768); } void mysrand(unsigned seed) { next = seed; }
sciko писал(а): ↑11.04.2011 17:01Вообще-то фундаментально они идентичны.
Распараллелить можно только чистые функции. Но вот ни один процедурный язык не проверяет чистоту функции (в отличии от Хаскеля состоит только из чистых функций и монад). Более того побочные эффекты или недетерминированость может скрываться где-то глубоко в стандартных библиотеках или написанных для непараллельного участка.
В этом смысле OpenMP более дружелюбен: учаски распараллеливания чётко отмечены и результат их работы более-менее понятен.
DESCRIPTION
The rand() function returns a pseudo-random integer in the range 0 to RAND_MAX inclusive (i.e., the mathe‐
matical range [0, RAND_MAX]).
The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be
returned by rand(). These sequences are repeatable by calling srand() with the same seed value.
If no seed value is provided, the rand() function is automatically seeded with a value of 1.
The function rand() is not reentrant or thread-safe, since it uses hidden state that is modified on each
call. This might just be the seed value to be used by the next call, or it might be something more elabo‐
rate. In order to get reproducible behavior in a threaded application, this state must be made explicit;
this can be done using the reentrant function rand_r().
Like rand(), rand_r() returns a pseudo-random integer in the range [0, RAND_MAX]. The seedp argument is a
pointer to an unsigned int that is used to store state between calls. If rand_r() is called with the same
initial value for the integer pointed to by seedp, and that value is not modified between calls, then the
same pseudo-random sequence will result.
The value pointed to by the seedp argument of rand_r() provides only a very small amount of state, so this
function will be a weak pseudo-random generator. Try drand48_r(3) instead.
drBatty писал(а): ↑12.04.2011 16:37обычно таки "да". Т.е. результат гонки недетерминирован, а следовательно непредсказуем. Потому и весь алгоритм недетерминирован, если кодер хоть раз проворонил гонки. Ну а пользуясь стандартными функциями С/С++ проворонить очень легко - они практически все с побочными эффектами.