Установка R в Ubuntu. Запуск функцій R на кількох машинах Використання кількох ядер усередині вузла

Жарознижувальні засоби для дітей призначаються педіатром. Але бувають ситуації невідкладної допомоги за лихоманки, коли дитині потрібно дати ліки негайно. Тоді батьки беруть на себе відповідальність і застосовують жарознижувальні препарати. Що можна давати дітям грудного віку? Чим можна збити температуру у старших дітей? Які ліки найбезпечніші?

Ви можете використовувати system() та Rscript для запуску сценарію як асинхронного фонового процесу:

system ( "Rscript -e "source(\"your-script.R\")"", wait = FALSE ) ... save.image ("script-output.RData" ) cat ("Script completed\n\n" )

Надіюсь це допоможе!

Я хочу виконати R сценарій у фоновому режимі з консолі R.

З консолі я зазвичай запускаю R-скрипт як джерело ("~ / .active-rstudio-document). Мені потрібно почекати, поки скрипт не буде завершено, щоб продовжити роботу. Натомість я хочу, щоб R працював у фоновому режимі, поки я можу продовжити роботу в консолі.Якщо я повинен бути повідомлений, коли R завершує команду джерела.Чи можливо це в R?

Це може бути дуже корисним, оскільки ми часто бачимо, що робота займає багато часу.

PS - Я хочу, щоб вихідний скрипт працював у тому самому просторі пам'яті, а не в новому. Тому рішення, такі як fork, system тощо. буд., нічого очікувати працювати мені. Я бачу, чи можу запустити R-скрипт як окремий потік, а не окремий процес.

При роботі з R скриптом може знадобитися оновлювати його автоматично. Пакет “taskscheduleR” допомагає налаштувати розклад для запуску R скрипту в Windows Task Schedule щодня, щотижня, кожні N хвилин після запуску Windowsі так далі.

  1. Встановлюємо пакет “taskscheduleR” library(devtools) install.packages("devtools") install_github("jwijffels/taskscheduleR") library(taskscheduleR)

    Використовуємо пакет "devtools", який дозволяє завантажувати та встановлювати пакети безпосередньо з GitHub.

  2. Далі для налаштування запуску скрипта можна скористатися або інтерактивним налаштуванням через форму, або написавши кілька рядків коду.

Налаштування розкладу R скрипту в Task Scheduler через Addins:

Налаштування розкладу R скрипта через функції пакету taskscheduleR:

Функції пакету:

  • Отримати список усіх завдань у Windows Task Sheduler
  • Видалити завдання з Windows Task Sheduler
  • Додати завдання запуску R скрипту
    • Доступні такі розклади: 'ONCE', 'MONTHLY', 'WEEKLY', 'DAILY', 'HOURLY', 'MINUTE', 'ONLOGON', 'ONIDLE'
## Вказуємо назву файлу R скрипта для подальшої роботи з ним myscript<- system.file("extdata", "helloworld.R", package = "taskscheduleR") ## Запуск скрипта разово через 35 секунд taskscheduler_create(taskname = "myscript", rscript = myscript, schedule = "ONCE", starttime = format(Sys.time() + 35, "%H:%M")) ## Запуск скрипта ежедневно в 10:15, начиная с завтрашнего дня ## Важно: необходимо поменять формат даты, если он не совпадает с тем, что стоит на компьютере (пример: %m/%d/%Y) taskscheduler_create(taskname = "myscriptdaily", rscript = myscript, schedule = "DAILY", starttime = "10:15", startdate = format(Sys.Date()+1, "%d/%m/%Y")) ## Запуск скрипта каждую неделю в 10:15 по понедельникам taskscheduler_create(taskname = "myscript_mon", rscript = myscript, schedule = "WEEKLY", starttime = "10:15", days = "MON") ## Запуск каждые 5 минут, начиная с 10:15 taskscheduler_create(taskname = "myscript_5min", rscript = myscript, schedule = "MINUTE", starttime = "10:15", modifier = 5) ## Получить data.frame со всеми задачами tasks <- taskscheduler_ls() str(tasks) ## Удалить задачи taskscheduler_delete(taskname = "myscript") taskscheduler_delete(taskname = "myscriptdaily") taskscheduler_delete(taskname = "myscript_,mon") taskscheduler_delete(taskname = "myscript_5min") taskscheduler_delete(taskname = "myscript_withargs_a") taskscheduler_delete(taskname = "myscript_withargs_b")

На що звертаємо увагу:

  • Формат дати. Він має співпадати з форматом дати на комп'ютері. В іншому випадку отримаємо або помилку налаштування розкладу запуску скрипта, або зовсім іншу дату.
  • Активність комп'ютера. Комп'ютер повинен бути увімкнений у момент запуску скрипту
  • Наявність інших розкладів скрипту. При налаштуванні нового розкладу з тією самою назвою попередній розклад видаляється.

R - популярна мова програмування з відкритим вихідним кодом, що спеціалізується на статистичних розрахунках та графіках. Він широко використовується статистиками для розробки статистичного програмного забезпечення та проведення аналізу даних. Однією із сильних сторін R є його розширюваність. Користувачі можуть створювати та публікувати власні пакети. R Спільнота дуже активна, постійно додаються користувацькі статистичні пакети для специфічних галузей науки. Що робить R застосовним у багатьох сферах.

CRAN (Comprehensive R Archive Network) - це набір сайтів (дзеркал) на яких розміщено безліч пакетів, і самі дистрибутиви R. Ви можете завантажити R з будь-якого з них, але ми будемо використовувати RStudio.

У цьому посібнику ви дізнаєтесь як встановити та налаштувати R в Ubuntu 14.04. Більшість інструкцій підійдуть і для інших операційних систем, потрібно змінити лише кілька команд. На все у вас має піти не більше 10-15 хвилин.

Звичайно ж нам буде потрібно Ubuntu 14.04, оскільки саме на неї розрахована стаття і 1 Гігабайт оперативної пам'яті в системі. Якщо пам'яті недостатньо, необхідно підключити розділ підкачування.

Всі команди виконуються від звичайного користувача, якщо буде потрібен рут доступ ми використовуємо sudo.

Підготовка системи

Для встановлення R ми будемо використовувати APT (Advanced Packaging Tool). Для зберігання списку джерел, звідки будуть завантажені пакети, він використовує спеціальний файл. Це /etc/apt/sources.list. Якщо ми хочемо отримати найсвіжішу версію R, то потрібно додати правильний репозиторій до списку джерел. Для цього додамо наступний рядок в /etc/apt/sources.list, в Ubuntu 14.04 вона виглядатиме ось так, але для інших версій відрізнятиметься:

sudo sh -c “echo “deb http://cran.rstudio.com/bin/linux/ubuntu trusty/” >> /etc/apt/sources.list’

Репозиторій для своєї версії ОС можна дізнатися там

Для встановлення пакетів з цього репозиторію APT нам потрібно додати його публічний ключ. У Ubuntu CRAN підписано ключем із ID E084DAB9. Додаємо його до системи:

gpg -keyserver keyserver.ubuntu.com -recv-key E084DAB9

А потім в apt:

gpg-a-export E084DAB9 | sudo apt-key add -

Встановлення R

Тепер, коли APT налаштований правильно, ми можемо переходити до установки.

Спочатку потрібно оновити список доступних пакетів, оскільки ми змінили джерела:

sudo apt-get update

Тепер можемо встановлювати R. Прапор y автоматично підтверджує встановлення програми:

sudo apt-get -y install r-base

Тепер у вас у системі встановлена ​​сама остання версія R. Можете протестувати її виконавши:

Ви побачите щось на кшталт цього:

R version 3.2.1 (2015-06-18) - "World-Famous Astronaut"
Copyright (C) 2015 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
Ви маєте можливість відновити це під певними умовами.
Type 'license()' або 'licence()' for distribution details.

Natural language support but running in English Locale

R is collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R або R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

Зараз ви в інтерактивній консолі R і можете виконувати будь-які команди R. Для виходу використовуйте функцію:

> q(save = "no")

Встановлення пакетів R із CRAN

За замовчуванням R встановлює кілька стандартних пакетів, але ви, напевно, захочете встановити додаткові пакети. Для цього потрібно не менше 1 Гб оперативної пам'яті.

Як згадувалося раніше в CRAN розміщено не тільки сам R але й багато додаткових пакетів. Для встановлення або оновлення пакетів із CRAN необхідно використовувати R функцію install.packages(). Наприклад, якщо ви хочете встановити пакет package використовуйте наступну команду:

> install.packages(«package»)

Варто зауважити, що пакет буде встановлений тільки для поточного користувача та іншим буде недоступним.

Можна встановити пакет R для всіх користувачів, для цього потрібно використовувати права суперкористувача. Як приклад давайте встановимо пакет shiny, який дуже популярний серед розробників web додатків на R. Один із способів встановлення пакета від суперкористувача - увійти як суперкористувач, запустити R і викликати функцію install.packages(). Але це робити не рекомендується. Ми можемо просто запустити команду R за допомогою sudo. Параметр repo вказує з якого репозиторію буде завантажено пакет.

sudo su - -c "R -e \"install.packages('shiny', repos = 'http://cran.rstudio.com/')\"»

Тепер пакет буде доступний всім користувачам. Давайте перевіримо. Запустіть R:

Завантажте пакет:

> library(shiny)

Як бачите, команда не викликала помилок. Тепер закрийте R:

> q(save = "no")

Встановлення пакету DevTools

Пакети розміщені в CRAN можуть бути встановлені функцією install.packages(), але є ще багато пакетів розміщених на GItHub. Для встановлення пакетів R із Github потрібно використовувати пакет DevTools. Давайте його встановимо. Для роботи пакет вимагає три бібліотеки libcurl4-gnutils-dev, libxml2-dev і libssl-devc встановіть їх:

sudo apt-get -y install libcurl4-gnutls-dev libxml2-dev libssl-dev

Тепер можна встановлювати devtools. Не забудьте, що його потрібно встановити для всіх користувачів як описано вище.

sudo su - -c "R -e \"install.packages('devtools', repos='http://cran.rstudio.com/')\"»

Установка devtools займе кілька хвилин.

Встановлення пакетів R із GitHub

Тепер, коли DevTools встановлено, ми можемо встановити будь-який пакет з GitHub, використовуючи функцію install_github(). Так само, як і в установці з CRAN, ви повинні виконувати команду від суперкористувача для встановлення пактів для всіх користувачів. Давайте спробуємо встановити shinyjs з GitHub котрий додає функціональність до пакету shinyjs. Пакет у GitHub визначається його автором та назвою:

sudo su - -c "R -e \"devtools::install_github('daattali/shinyjs')\"»

Давайте перевіримо коректність установки shinyjs завантаживши його. Запустіть R:

Спробуйте завантажити shinyjs:

> library (shinyjs)

ви вже знаєте як закрити інтерпретатор R:

> q(save = "no")

Наступні кроки

Тепер у вас у системі встановлений та налаштований повністю робочий інтерпретатор мови R. Для отримання більш детальної інформації можете відвідати

Щоб створити змінну (наприклад, х) та присвоїти їй значення (наприклад, 1234) потрібно просто ввести команду х = 1234 . Тепер у будь-яких виразах ім'я змінної (у нашому випадку х) буде автоматично замінено значенням (у нас це 1234).

Щоб дізнатися про значення змінної, достатньо ввести назву змінної, і R видасть її значення. Виглядатиме це так:
> x=1234
> х
1234

Присвоюючи змінної нове значення, можна використовувати старе значення, тобто створювати конструкції типу
> a=5
> a
5
> a=a+3
> a
8

Важливо знати, що імена змінних можуть складатися з латинських літер обох регістрів, цифр і знаків підкреслення (наприклад, допустимі такі імена: a, x, x1, a_x, O_o, the_Variable_with_Long_Name, a459x4h36J4lbgT62). При цьому першим символом має обов'язково бути буква! Нарешті, регістр має значення, тобто RainForest та RainFOrest – це різні змінні.

Вектори чи як працювати з рядами даних?

Що таке вектори у R?

Припустимо, у нас є група із 5 осіб, і нам треба зберегти їх вік. Можна створити п'ять змінних, наприклад
> age_1 = 25
> age_2=20
> age_3=9
> age_4=44
> age_5=37
Однак зручніше створити одну змінну, в яку помістити всі 5 значень. Такий ряд даних, об'єднаних одним ім'ям, що зберігається в певному порядку - це масив даних або вектор.

Assign("age",c(25,20,9,44,37))
або скорочено: age

Тепер кожен окремий елемент можна викликати за його порядковим номером в ряду, наприклад, четвертий елемент можна отримати так:
> age
44
З такими окремими елементами можна робити ті самі операції, що й із звичайними числами

Функція append, або як додати елементи до існуючого вектора?

Допустимо, у нашій групі з'явилася ще одна людина, вік якої 31 рік. Ми можемо створити заново вектор age, але тепер із шести елементів замість п'яти. Однак є інший спосіб - використовувати функцію append:
> append(age,31)
25 20 9 44 37 31
Зауважу, що ми могли б вставити кілька значень, згадавши функцію c():
> append(age,c(31,33,35))
25 20 9 44 37 31 33 35

Також функція дозволяє вставити елементи будь-де вектора за допомогою параметра after. За промовчанням встановлено значення after=length(x), тобто елементи додаються до кінця. Але припустимо, ми захочемо вставити нашу шосту людину після другої:
> append(age, 31, after=2)
25 20 31 9 44 37

Операції з векторами чи що можна робити з векторами?

Можна одночасно оперувати всіма елементами вектора. Так додавання числа до вектора рівносильне додавання цього числа до кожного елемента вектора. Або, наприклад, щоб вивести, скільки десятків років прожила кожна людина з нашого прикладу, можна зробити так:
> age/10
2.5 2.0 0.9 4.4 3.7

Аналогічно із додаванням, відніманням та іншими операціями, описаними в пункті про

Як порівнювати вектори, елементи векторів?

Припустимо, потрібно з'ясувати, які елементи вектора (нехай буде той самий age) більше за певну кількість (наприклад, хто з нашої маленької вибірки повнолітній). R для кожного елемента скаже, чи виконується умова, тобто TRUE (вірно) або FALSE (не вірно) Виглядатиме приблизно так:
>age
25 20 31 9 44 37
> age >= 18
TRUE TRUE FALSE TRUE TRUE

Але може знадобитися отримати одну відповідь, наприклад, чи правильно, що всі елементи відповідають умові? чи є взагалі елементи, які відповідають умові? Для цього використовуємо дві функції, відповідно, all() та any()

all(x1,x2,...,xn) - відповість питанням, чи правильно, що це умови (x1, x2, ... і xn) правильні? тобто це логічна кон'юнкція. Наприклад:
> all (age >= 7, age TRUE
# дійсно, всі випробувані не молодше семи і молодше шістдесяти
> all (age >=18, 1 > 0)
FALSE
хоча одиниця, звичайно, більше нуля, але серед наших піддослідних є один дев'ятирічний, тому не вірно

any(x1,x2,...,xn) - відповість питанням, чи є серед умов (x1, x2, ..., xn) хоч одне правильне? тобто це логічна диз'юнкція. Приклад:
> any (age >=18, 1 > 0)
TRUE

Зрештою, можна порівнювати між собою два вектори. Але для цього потрібно або щоб довжина більшого була кратна довжині меншого або щоб довжини дорівнювали. Приклади:
> a > a > b
FALSE FALSE FALSE TRUE TRUE

Як встановити послідовність чисел?

  • оператор:
  • seq(from,to,by,length,along) - створює послідовність, починаючи з from, закінчуючи to з кроком by. Можна встановити довжину ряду параметром length або прирівняти по довжині до іншого вектора along . Аргументи: from, to, by, length, along (така сама довжина як...)
  • rep(a, times, each) - повторювати вектор a times разів або each разів кожен елемент a. Аргументи: вектор, times, each

Сортування

  • sort(v,increasing) - сортує вектор v; increasing - булев, true - по зростанню, false - за спаданням, можна замість цього написати increasing = decreasing;
  • order()

Одна з переваг R – легкість, з якою можна скористатися перевагами паралельного програмування для прискорення обчислень. У цій статті ми розповімо, як перейти від запуску функцій на кількох процесорах чи ядрах до запуску кількох машинах (з метою ще більшого масштабування та прискорення).

Сам собою R не призначений для паралельних обчислень. У ньому немає безлічі паралельних конструкцій, доступних користувачеві. На щастя, завдання обробки даних, для вирішення яких ми найчастіше використовуємо R, дуже добре підходять для паралельного програмування, і є ряд відмінних бібліотек, які використовують. Ось три основні шляхи скористатися перевагами паралелізації, що надається бібліотеками:

  • Підключайте більш потужні паралельні бібліотеки, наприклад Intel BLAS(доступна під Linux, OS X та Windows як частина дистрибутива Microsoft R Open). Це дозволить замінити вже використовувані бібліотеки їх паралельними версіями, завдяки чому отримаєте прискорення (на відповідних завданнях, наприклад, пов'язаних з лінійною алгеброю lm()/glm()).
  • Винесіть обробку завдань моделювання з R у зовнішню бібліотеку для паралелізації. Це стратегія, яку використовують такі системи: методи rx від RevoScaleR (тепер Microsoft Open R), методи h2o від h2o.ai, RHadoop.
  • Використовуйте утиліту parallel у R, щоб запускати функції на інших примірниках R. Ця стратегія з "Невеликого введення в паралельне програмування на R" і ряду бібліотек на основі parallel. Фактично це реалізація віддаленого виклику процедури через сокет чи мережу.

Розглянемо докладніше третій підхід.

Фактично, третій підхід є дуже дрібно докладний віддалений виклик процедури. Він залежить від передачі копій коду та даних на віддалені процеси та подальше повернення результатів. Це погано підходить для дуже маленьких завдань, але чудово – для прийнятної кількості середніх або великих. Ця стратегія використовується в бібліотеці R parallel і в бібліотеці Python multiprocessing (хоча з multiprocessing для Python може знадобитися ряд додаткових бібліотек, щоб перейти від однієї машини до кластерних обчислень).

Цей метод може бути менш ефективним і менш складним, ніж методи розподіленої пам'яті, але покладаючись на передачу об'єкта, можна дуже легко поширити техніку від однієї машини на кілька («кластерні обчислення»). Саме це ми зробимо за допомогою коду R у цій статті (перехід від однієї машини до кластера призведе до численних проблем систем/мережі/безпеки, і з ними доведеться справлятися).

Вам знадобиться весь код R з попередньої статті. Також передбачається, що ви можете налаштувати ssh, або у вас є людина, яка може допомогти з налаштуванням. Замість запуску паралельного кластера командою “ parallelCluster<- parallel::makeCluster(parallel::detectCores()) ” сделайте следующее.

Зберіть список адрес машин, до яких можна застосувати ssh . Це складна частина залежить від операційної системи і може вимагати допомоги, якщо ви раніше цього не робили. У цьому прикладі я використовую IPv4 адреси, а для Amazon EC2 – імена вузлів.

У моєму випадку список такий:

  • Моя машина (основна): "192.168.1.235", користувач "johnmount"
  • Інша машина Win-Vector LLC: "192.168.1.70", користувач "johnmount"

Зверніть увагу, ми не збираємо паролі, припускаючи, що встановлені правильні authorized_keys і пари ключів у конфігураціях ".ssh" всіх цих машин. Будемо називати машину, з якою здійснюватиметься розрахунок загалом, «первинною».

Обов'язково варто спробувати всі ці адреси з «ssh» у терміналі перед тим, як використовувати їх у R. Також адреса машини, обраної «первинною», повинна бути досягнута з робочих машин (тобто не можна використовувати «localhost» або вибирати недосяжну машину "первинної"). Спробуйте вручну ssh між первинною та іншими машинами, і у зворотний бік, після чого налаштування можна буде використовувати в R.

Коли системні налаштування позаду, частина R буде виглядати так. Запустіть ваш кластер:

Primary<- "192.168.1.235" machineAddresses <- list(list(host=primary,user="johnmount", ncore=4), list(host="192.168.1.70",user="johnmount", ncore=4)) spec <- lapply(machineAddresses, function(machine) { rep(list(list(host=machine$host, user=machine$user)), machine$ncore) }) spec <- unlist(spec,recursive=FALSE) parallelCluster <- parallel::makeCluster(type="PSOCK", master=primary, spec=spec) print(parallelCluster) ## socket cluster with 8 nodes on hosts ## ‘192.168.1.235’, ‘192.168.1.70’

От і все. Тепер можна запускати ваші функції на кількох ядрах кількох машин. Для правильних завдань прискорення буде суттєвим. Завжди має сенс діяти покроково: спочатку напишіть простий hello world на вашому кластері, потім переконайтеся, що менша версія ваших розрахунків працює локально, і тільки після цього переносіть роботу в кластер.

Є й інший спосіб працювати з кластерами в R. Для початку нам знадобиться версія R із передозлатненими пакетами Rmpi ​​та snow. Для цього я пропоную білд R HSPCC, підтримуваний Каспером Деніелом Хансеном. Ось інструкції щодо встановлення.

Ми розглянемо ще два простих методи паралельної обробки даних у R. Перший, який використовує пакет multicore, обмежений процесорами на одному вузлі. І хоча це може здатися серйозним недоліком, фактично може виявитися сильною перевагою, оскільки взаємодія між процесами буде на кілька порядків швидше. Друга опція - використовувати пакет snow, що дозволяє використовувати для обчислень підкластера MPI (інтерфейси передачі даних між вузлами).

Використання кількох ядер усередині вузла

Пакет multicore дуже ефективний у прискоренні простих обчислень, використовуючи більше одного ядра процесора в кожний момент часу. Його дуже легко застосовувати та швидко реалізувати.

Запустіть процес на вузлі кластера з кількома процесорами, набравши таку команду:

Qrsh-l mcmc-pe local 10-12

Зверніть увагу, тут ми просимо 10-12 процесорів на одному вузлі у черзі mcmc. Кількість доступних ядер можна переглянути в змінному оточенні NSLOTS, доступному в R за допомогою такої команди:

As.integer(Sys.getenv("NSLOTS"))

Наступний крок – запустити R та завантажити бібліотеку multicore. Нарешті, можна продовжити використанням команди mclapply замість lapply в R (передаючи кількість використовуваних ядер як аргумент mc.cores).

Використання snow між кількома вузлами

Нижче - інструкція у вигляді простого прикладу, як R підняти кластер MPI і як використовувати кластер для простих обчислень.

Для запуску кластера MPI з 12 вузлами (ядрами) потрібно набрати таке:

Qrsh -V -l cegs -pe orte 12 /opt/openmpi/bin/mpirun -np 12 ~hcorrada/bioconductor/Rmpi/bstRMPISNOW

Ця команда повинна запустити 12 екземплярів R, один із яких буде первинним. Зверніть увагу, стартовий процес був у черзі cegs. Потім ви можете користуватися вузлами, встановленими за допомогою mpirun, набравши R таке:

Cl<- getMPIcluster()

Потім можна переглянути та скористатися потрібними вам командами snow. Наприклад,

ClusterCall(cl, function() Sys.info())

видасть список вузлів вашого кластера (якщо точніше, 11 запущених робочих вузлів). список доступних команд.

Коли обчислення на кластері завершено, потрібно закрити вузли наступною командою:

StopCluster(cl)

Попередження: переконайтеся, що ви не скасували процеси R натисканням комбінації клавіш Ctrl+C. Це може викликати проблеми зі snow.

Приклад: порівняння послідовної та паралельної обробки

> f.long<-function(n) { + xx<-rnorm(n) + log(abs(xx))+xx^2 + } #Использование multicore ############ >system.time(mclapply(rep(5E6,11),f.long,mc.cores=11)) user system elapsed 26.271 3.514 5.516 #Використання snow через MPI ############ > system. time(sapply(rep(5E6,11),f.long)) user system elapsed 17.975 1.325 19.303 > system.time(parSapply(cl,rep(5E6,11),f.long)) user system elapsed 4.228 4.3.

Зверніть увагу, паралельна обробка зі snow дає поліпшення більш ніж 50% часу обчислення. Хоча можна припускати, що поліпшення має становити 10/11=91%, важливо пам'ятати, що процесори не обов'язково знаходяться на тому самому вузлі, і взаємодія між вузлами може бути досить повільним. Ця взаємодія може бути настільки повільною, що процедура на multicore без неї може дати 40% поліпшення часу обчислення.

Відповідно, варто пам'ятати, що переваги в часі обчислення від використання більш ніж одного вузла кластера значною мірою можуть нівелюватися часом, що йде на взаємодію між вузлами. Звичайно ж, це залежить від обчислень, що здійснюються, і способу їх реалізації.

Підтримайте проект - поділіться посиланням, дякую!
Читайте також
Як встановити безкоштовний антивірус аваст Як встановити безкоштовний антивірус аваст Як очистити комп'ютер від вірусів самостійно Як очистити комп'ютер від вірусів самостійно Як повністю очистити комп'ютер від вірусів Як повністю очистити комп'ютер від вірусів