parallel-programming/1/openmp/windows/zadanie1_Windows_Remastered...

190 lines
5.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Так, братиш, перед тем, как начнём разбираться с прелестями OpenMP, его сначала надо включить в настройках.
// Для этого перейди вверху на вкладку "Проект", затем в меню последней строкой будут свойства твоего проекта. *Тык* туда.
// Затем справа в меню выбери "C++". Слева в таблице найди строку "Поддержка Open MP" и напротив в выпадающем меню выбери "Да (/openmp)".
// Ты крутой. А теперь слушай сюда.
// Включаем всякую хрень
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <omp.h>
#include <locale>
// Это - функция проверки числа на "просто(а)ту" числа. Если число простое (ни на что не делится), то она вернёт true
bool is_prime(int num) {
if (num <= 1) {
return false;
}
for (int i = 2; i <= sqrt(num); i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
// Главная функция. Здесь происходит вся магия. *вжух*
int main() {
// Мы же русские?
setlocale(LC_ALL, "Russian");
// Короче, для простоты я буду называть это "главным промежутком", где low_lim - начало, а up_lim - конец
long long int low_lim = 1000000000LL; // 1 миллиард
long long int up_lim = 100000000000LL; // 100 миллиардов
// А вот это - наш маленький промежуток. Он нам нужен, чтобы найти все подходящие простые числа.
// Здесь - new_low_lim - начало, представляющее собой корень четвертой степени из начала нашего главного промежутка,
// а new_up_lim - то же самое, но с концом
long long int new_low_lim = pow(low_lim, 1.0/4.0);
long long int new_up_lim = pow(up_lim, 1.0/4.0);
// Это вектор, в котором у нас будут простые числа, которые мы будем возводить в 4-ю степень,
// потому что мы же ищем числа с тремя делителями? А простое число в 4-й степени - и есть такое число. Можешь сам проверить
std::vector<long long int> primes;
// Ооо, моя любимая часть. Здесь мы говорим OpenMP распараллелить поток. "for" нужен для того, чтобы каждый поток не создавал новый for,
// потому что в таком случае каждый поток просто создаст свой цикл, и все они будут работать независимо
#pragma omp parallel for
// Вот здесь уже будет несколько потоков. Сколько? Я хз, братан, можешь погуглить свои характеристики
// Даже как-то странно быть комментарием внутри потоков. Если они это читают, то печенек им и частоты побольше)
// Короче, здесь мы вводим цикл for, который идет от меньшей границы к большей нашего младшего промежутка
for (long long int i = new_low_lim; i <= new_up_lim; i++) {
long long int number = pow(i, 4);
// Опа, крч, дойдя до сюда, поток будет "ждать" завершение записи числа другим потоком.
// Это нужно, чтобы не возникало datarace-а (гугл в помощь)
#pragma omp critical
{
// Провер очка того, что старшее число входит в промежуток и младшее - простое число.
// Для проверки на просто(а)ту мы вызываем функцию is_prime (ты же не забыл о ней?) и передаём ей параметр i
if (number >= low_lim && number <= up_lim && is_prime(i)) {
// Коли так, то заталкиваем младшее в наш вектор
primes.push_back(number);
}
}
}
// Путь к файлу, в который мы записываем числа с тремя делителями. Только измени путь на свой, а то ещё на мой комп ненароком запишешь
std::ofstream output_file("C:\\Users\\ilyas\\Desktop\\result.txt");
// Если файл открыт,..
if (output_file.is_open()) {
// ... то все числа из нашего вектора записываем в файл
for (const auto& prime_power : primes) {
output_file << prime_power << std::endl;
}
// Закрываем файл
output_file.close();
std::cout << "Результаты записаны в файл result.txt на рабочем столе." << std::endl;
} else {
std::cerr << "Ошибка открытия файла для записи." << std::endl;
}
// Пусть будет
return 0;
}
// Любопытный, да?