- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
#include <iostream>
#include <thread>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iterator>
#include <future>
constexpr std::size_t array_size = 1e7;
constexpr std::size_t chunks_number = 1e3;
double local_pi(const std::size_t array_length)
{
std::vector<std::pair<double, double>> array_xy;
array_xy.reserve(array_length);
std::generate_n(std::back_inserter(array_xy), array_length, [](){
return std::make_pair(rand()/static_cast<double>(RAND_MAX),
rand()/static_cast<double>(RAND_MAX));
});
std::vector<bool> bool_z;
bool_z.reserve(array_length);
auto bool_z_insterter = std::back_inserter(bool_z);
std::for_each(array_xy.cbegin(), array_xy.cend(), [&](const std::pair<double, double>& ref){
const auto func = [](const std::pair<double, double>& ref){
return sqrt(pow(ref.first, 2) + pow(ref.second, 2)) <= 1.0;
};
bool_z_insterter = func(ref);
});
const auto sum = 4.0 * (std::accumulate(bool_z.cbegin(), bool_z.cend(), 0.0)/array_length);
return sum;
}
int main(){
const auto concurrency_level = std::thread::hardware_concurrency();
std::vector< double > chunks_vector;
chunks_vector.reserve(chunks_number);
for (std::size_t j = 0; j < chunks_number; ++j) {
std::vector<std::future<double>> futures;
futures.reserve(concurrency_level-1);
for (std::size_t i = 0; i < concurrency_level-1; ++i){
auto f = std::async(std::launch::async, local_pi, array_size/concurrency_level);
futures.push_back(std::move(f));
}
auto pi = local_pi(array_size/concurrency_level);
for (auto&& x : futures ){
pi += x.get();
}
pi /= concurrency_level;
chunks_vector.push_back(pi);
}
const auto total_pi = std::accumulate(chunks_vector.cbegin(), chunks_vector.cend(), 0.0)/chunks_vector.size();
std::cout << "Pi equals = " << std::scientific << total_pi << std::endl;
return 0;
}
Xom94ok 10.02.2014 21:53 # +5
bormand 10.02.2014 22:40 # +5
Кстати потестил сейчас каноничный рандом (std::mt19937_64 + std::uniform_real_distribution<double>) - и у меня челюсть отпала: он в 100(!) раз быстрее rand(). (Тестил на упрощенном коде, с выпиленными массивами).
UPD: А если убрать всю эту шелуху с многопоточностью (concurrency_level = 1) - то вдвое.
Значит или в rand() упрятан мутекс, или это thread-local переменная для seed'а в нем так ужасно сказывается на перфомансе.
Мораль: rand() - сраное говно, как и любая функция, которая пользуется глобальным состоянием. А генераторы с локальным состоянием рулят ;)
bormand 10.02.2014 22:52 # +3
west_coast_coders 11.02.2014 00:42 # +3
То есть rand() - вдвойне УГ
LispGovno 11.02.2014 09:16 # 0
bormand 11.02.2014 09:30 # +2
TarasB 11.02.2014 09:24 # +1
bormand 11.02.2014 09:57 # 0
Среди прочего линейно-конгруэнтного говна с неявным глобальным состоянием (скажи "нет" многопоточности) - он крутой ;)
Но согласись, кресто11блядский <random> (он же boost::random) няшней на порядки :3
defecate-plusplus 11.02.2014 10:02 # 0
bormand 11.02.2014 10:07 # +2
TarasB 11.02.2014 10:20 # 0
надеюсь, что это поможет точно портировать некоторые вещи, тонко подогнанные под конкретный генератор
defecate-plusplus 11.02.2014 10:31 # +1
подставь константы из дельфячего рандома да перепроверь
насколько я понимаю, это
defecate-plusplus 11.02.2014 10:37 # 0
bormand 11.02.2014 10:42 # 0
bormand 11.02.2014 10:51 # 0
Короче 0 туда надо передавать ;)
4294967296 по сути тоже 0, но выдаст ворнинг. Некрасиво.
defecate-plusplus 11.02.2014 10:55 # 0
надо где-то ещё чего-нить подмешать
bormand 11.02.2014 14:53 # 0
В целом сам генератор подходит, а вот uniform_int_distribution - не совпадает, и нужно мутить tblib::almost_uniform_int_distribution через умножение и старшую часть ;)
bormand 11.02.2014 10:39 # 0
О, так ты сдался и все-таки поставил буст?
TarasB 11.02.2014 11:04 # 0
только в класс обернул
Кстати, вопрос: какого хуя гцц ругается на такаую перегрузку:
int random(int n);
float random();
bormand 11.02.2014 11:09 # 0
P.S. А, оно у тебя с random() из <stdlib.h> конфликтануло. Лишний повод юзать namespace :)
TarasB 11.02.2014 11:12 # 0
А теперь вызови float f = pasrnd.random();
int n = pasrnd.random(5);
bormand 11.02.2014 11:18 # 0
Все нормально, как и ожидалось.
P.S. 146%, что у тебя n с дефолтом: Тогда действительно конфликтанут.
TarasB 11.02.2014 12:56 # +1
я вчера весь день угорал на крестофоруме, мне объясняли, что дефолтные аргументы в конструкторах Point3D - это нормально и писать
Point3D(1) намного лучше, чем Point3D(1.0f, 0.0f, 0.0f)
WGH 11.02.2014 13:15 # +2
https://www.opengl.org/wiki/Data_Type_%28GLSL%29#Constructors
С векторами, соглашусь, спорно, а вот с матрицами весьма удобно.
bormand 11.02.2014 13:15 # 0
А не vec3(1.0, 0.0, 0.0) разве?
WGH 11.02.2014 13:18 # 0
>If there is a single scalar parameter to a vector constructor, it is used to initialize all components of the
constructed vector to that scalar’s value. If there is a single scalar parameter to a matrix constructor, it is
used to initialize all the components on the matrix’s diagonal, with the remaining components initialized
to 0.0.
TarasB 11.02.2014 13:23 # 0
vec3(1) - это может быть только vec3(1.0f, 0.0f, 0.0f) и ничем другим это быть не может и что я тормоз, что не понимаю этой очевидности.
TarasB 11.02.2014 13:17 # 0
с векторами не то что спорно, это просто крестоблядское мудоёбство экономить пару символов и ради чего
bormand 11.02.2014 11:15 # 0
TarasB 11.02.2014 11:28 # 0
inline не потому что я царь, а потому что линковщик матерится
TarasB 11.02.2014 11:29 # 0
bormand 11.02.2014 12:23 # 0
bormand 11.02.2014 12:41 # 0
После NextSeed() получаем 3006477056, которое по показаниям питона и хаскеля должно дать (3006477056 * 100) `div` (2^32) = 69. Код Тараса возвращает нам 69. Крестокод какого-то хуя - 70.
TarasB 11.02.2014 12:55 # 0
> 3006477056*100 / (2**32)
> 69.99999880790710449
походу говнобуст зачем-то воткнул плавучку
bormand 11.02.2014 13:26 # 0
Вот такой код там для целых типов: http://pastebin.com/CuchWzhY
Будем разбираться ;)
TarasB 11.02.2014 13:33 # 0
Да, в этом надо долго разбираться...
bormand 11.02.2014 13:59 # +2
Все, разобрался. В общем тут юзается точный алгоритм с отбрасыванием (например для генерации чисел от 0 до 99, последние 97 чисел от 4294967200 до 4294967296 тупо выкидываются и у генератора запрашивается новое, остальные же нарезаются на равные интервалы по 100). Вот из-за этого / scaling и получается несовпадение на границах интервалов (здесь все интервалы равные, в делфи - 3 штуки на 1 число меньше). А если бы попалось одно из тех 96 чисел - произошел бы рассинхрон с твоим алгоритмом.
Так что если нужен в точности дельфиний генератор - заюзать uniform_int_distribution<int> dist(0, 99) нельзя.
bormand 11.02.2014 14:07 # 0
errata:
последние 97 чисел от 4294967200 до 4294967296 тупо выкидываются читаем как последние 96 чисел от 4294967200 до 4294967295 тупо выкидываются
в делфи - 3 штуки на 1 число меньше читаем как в делфи - 4 штуки на 1 число меньше
bormand 11.02.2014 13:33 # 0
Что-то херня какая-то. Судя по этому коду он должен отбрасывать неудачные рандомы (собственно один из кошерных и точных алгоритмов по преобразованию диапазонов рандома). Но он же не отбрасывает (т.к. рассинхрона этого и твоего рандома после таких ситуаций не происходит), а работает как на флоатах ;(
Ничего не понимаю. Ну не может же оно попадать во вторую специализацию, где true_type и работа с флоатами.
UPD: Не тот класс смотрел, сейчас раскурю тот, который надо.
Abbath 17.01.2020 16:21 # +1
bootcamp_dropout 17.01.2020 16:40 # 0
bormand 11.02.2014 14:50 # 0
TarasB 11.02.2014 15:05 # 0
Очевидно, что дефолтного значения там быть не могло, я не настолько ебанулся.
roman-kashitsyn 11.02.2014 11:18 # +2
Abbath 11.02.2014 02:00 # +2
1)Смотри как я могу
2)STL дрочерство
3)саморазвитие
4)тренировка парного программирования
А преподу сдается матлабовский код.
Xom94ok 11.02.2014 05:14 # +3
Я просто сам над оуеими халявщиками издевался: препод ожидает простую сишную программу, демонстрирующую алгоритм, а ему преподносят приплюсплюснутое нечто, полное СТЛа :)
wvxvw 11.02.2014 08:57 # 0
Я бы на месте преподавателя за такие названия и форматирование заставлял пистать гусиным пером в прописи.
Abbath 11.02.2014 10:03 # 0
wvxvw 11.02.2014 10:01 # 0
Без извлечения корней в каждой итерации.
wvxvw 11.02.2014 10:26 # 0
Лол, не, тоже говно, вот так надо распараллеливать!
PS. Я видел и не таких докторов, которые программируют на уровне бухгалтерши заведующей 1С-предприятием. Степень совсем не показатель.
bormand 11.02.2014 10:40 # 0
wvxvw 11.02.2014 11:20 # 0
mewmew 11.02.2014 14:14 # 0
Кто же для тебя скрипт модели напишет если не сам/а.
Abbath 11.02.2014 14:51 # +2
guest 11.02.2014 13:15 # 0
упоротый? в параллельном варианте там вообще цикла нет. Просто двумерный массив вместо одномерного.
wvxvw 11.02.2014 13:18 # 0
guest 11.02.2014 14:33 # 0
fixed. Да, будет быстрее чем цикл до миллиона.
wvxvw 11.02.2014 19:07 # 0
Хотя, конечно, это лаба, и точность тут не уперлась.
Abbath 13.02.2014 01:59 # 0
bormand 10.02.2014 21:54 # +3
Это точно. Полный пи.
bormand 10.02.2014 22:02 # +4
Abbath 10.02.2014 23:00 # −1
WGH 11.02.2014 12:33 # +6
!!!