Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

drand48 не безопасен в потоках?

27K
10 ноября 2019 года
mnanorn
78 / / 01.12.2013
Здравствуйте!

ОС Linux x64. Код:
Код:
/* compile: cc omp-pi.c -o omp-pi -lm -fopenmp  */

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include <math.h>

typedef unsigned long int large;

double getPi(large ndots){
    large i = 0;
    large goals = 0;

    #pragma omp parallel private(i)
    #pragma omp for
    for(i = 0; i < ndots; i++)
    #pragma omp critical
    {
            if(pow(drand48(), 2.0) + pow(drand48(), 2.0) <= 1)
            goals++;
    }
    printf("%li goalsn", goals);

    return (double)((4.0 * goals) / ndots);
}

int main(int argc, char* argv[]){
    large throws = 1000000000;
   
    double start = omp_get_wtime();
        printf("%.10fn", getPi(throws));
    printf("%.4f secn", omp_get_wtime() - start);

    return 0;
}
Суть: считаю пи методом Монте-Карло. Даже при количестве бросков 10'000'000'000 идёт потеря точности с третьего знака без
 
Код:
#pragma omp critical
    {
            if(pow(drand48(), 2.0) + pow(drand48(), 2.0) <= 1)
            goals++;
    }
То есть, если этот код не заключать в критическую секцию. Следовательно, drand48 - не потокобезопасен, хотя тут утверждается иное. Вопрос: подскажите потокобезопасный генератор double [0.0;1.0]. /dev/random не справляется с объёмом генерации. Почему не оставить критическую секцию: счёт на одном ядре в таком случае в три раза быстрее, чем на четырёх (bottle neck). Спасибо.
260
10 ноября 2019 года
Ramon
1.1K / / 16.08.2003
Здравствуйте,

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

Развернуто: с drand48, erand48_r и __drand48_iterate. Никаких намеков на синхронизацию мы там не наблюдаем, не так ли?

PS: Никогда не читайте мокрые фантазиии странных авторов, смотрите первоисточники.
PPS: Совсем по хорошему у каждого потока должно быть своё состояние для генератора, можно использовать drand48_r + srand48_r/seed48_r, однако портабельным сей код не будет.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог