| maisvendoo |
|
Темы:
68
Сообщения:
1142
Участник с: 10 октября 2012
|
Вчера собирал wine из исходников, интересно было просто, дык открыл для себя ключ к make, ключ -j8…. Ну процессор у меня Intel Core i7… Я чуть печенькой не подавился - все ядра загрузились на 100% wine минуты за три собрался. Вот и возник вопрос, а нельзя как-нибудь использовать эти же возможности в вычислительной математике, ибо решаю по долгу научной работы именно задачи ресурсоемких вычислений. Может есть среди арчеводов специалисты в области параллельных вычислений, которые могут подсказать куда копать и что использовать, литературу посоветуют. Ибо я мечусь то в NVidia CUDA, то ещё куда, и бью вопрос растопыркой. На деле в моем проекте нагружается на 100% только пока одно ядро, на которое я повесил, принудительно привязав к нему поток решения системы диффур
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb http://rusrailsim.org |
| sirocco |
|
|
Темы:
29
Сообщения:
2501
Участник с: 25 июля 2007
|
ИМХО, смотреть в сторону OpenCL (оно распределяет нагрузку не только на GPU, но и на CPU). На хабре небольшие обзоры были (“Используем OpenCL в Python”, “Введение в OpenCL”). |
| domov0y |
|
|
Темы:
5
Сообщения:
819
Участник с: 09 июля 2011
|
Если вы хорошо помните присказку:“женщина может выносить ребенка за девять месяцев, но девять женщин не смогут справиться с этой задачей за один месяц” то можете попробовать. Параллельные вычисления и кластеризация хороши там где нет рекурсии и много одинаковых задач с разными входными данными (приличный пласт задач из мат. физики и термодинамики, обсчет множества траекторий, моделирование динамических систем зависящих от множества факторов и т д) Еще все зависит от количества костылей вами используемых. В принципе если изобретать велосипед, то можно разделить вычисления на N процессов с получением данных через открытый tcp/udp порт. и выделить серверный процесс который будет рулить вычислениями. А если что нибудь попроще то тупо и банально курить ман про кластера, и подготовку (компиляцию с дополнительными параметрами и библиотеками) приложений для работы на вычислительных кластерах. Там достаточно приличная область знаний.
Да пребудет с вами знание ip адреса
|
| kurych |
|
|
Темы:
0
Сообщения:
1394
Участник с: 06 ноября 2011
|
Есть смысл смотреть в сторону MPI как технологии и OpenMPI как открытой реализации в частности. Википедия тоже дает широкий выбор путей. |
| sleepycat |
|
Темы:
98
Сообщения:
3291
Участник с: 19 июля 2011
|
ключ -j8 Про остальное, читать выше, я вопрос подобный не поднимал для себя.
Лозунг у них был такой: "Познание бесконечности требует бесконечного времени". С этим я не спорил, но они делали из этого неожиданный вывод: "А потому работай не работай — все едино". И в интересах неувеличения энтропии Вселенной они не работали. (с)
|
| cucullus |
|
Темы:
256
Сообщения:
3435
Участник с: 06 июня 2007
|
Если речь идёт о ядрах, то достаточно OpenMP. Модификация кода как правило ограничивается несколькими строками.
такие дела.
|
| sirocco |
|
|
Темы:
29
Сообщения:
2501
Участник с: 25 июля 2007
|
Если задача (и CPU – в i7 вроде есть) позволяет, то через OpenCL будет задействован AVXОба процессора содержат 4 реальных и 8 виртуальных ядер, а OpenCL как раз и сделан для того, чтобы все ядра использовать, но улучшение у нас гораздо больше, чем 4Х. А тут надо сказать спасибо Intel, которая в своей реализации OpenCL, добавила поддержку автоматической векторизации, т.е. без каких-либо изменений в коде, OpenCL использует SSE или AVX, в зависимости от того, что доступно. Учитывая, что SSE у нас 128битное, а AVX работает с 256битами, получается, что производительность должна подняться в 16X и 32X соответственно. |
| maisvendoo |
|
Темы:
68
Сообщения:
1142
Участник с: 10 октября 2012
|
Про OpenCL слышал, а вот про OpenMP и OpenMPI - впервые. За что люблю арч - всё перечисленное легко достал из репозитория. Буду разбираться, спасибо sirocco Есть ключики к компилятору gcc -march=corei7-avx и -mtune=corei7-avx. Не знаю правда насколько эффективны. Ну одними ключами проблемы не решатся, канеш
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb http://rusrailsim.org |
| cucullus |
|
Темы:
256
Сообщения:
3435
Участник с: 06 июня 2007
|
Ещё раз настоятельно рекомендую OpenMP. Он “из коробки” в gcc, модификация кода – мизерная, профит – моментальный.
такие дела.
|
| maisvendoo |
|
Темы:
68
Сообщения:
1142
Участник с: 10 октября 2012
|
С утра хотел написать, да провайдер меня подвел. Так вот, попробовал я OpenMP, благо чтобы его задействовать достаточно включить #include <omp.h> и поставить компилятору ключик -fopenmp cucullus Абсолютно согласен :) В качестве задачи для теста выбрал простенькую реализацию той задачи что решаю в своем проекте - движение поезда с учетом усилий возникающих в автосцепках. Сразу скажу, что приведенный пример это не та модель что используется в проекте, проект - здоровенное приложение с ООП и динамической загрузкой матмоделей подвижных единиц из *.so… Это предельно упрощенная постановка задача движения поезда из N подвижных единиц, с моделью сцепки в виде упругой связи, без учета сил сопротивления движению и прочего, то есть такой “сферический поезд в вакууме” Вот код с применением OpenMP
//==============================================================================
//
// Тестовая задача реализации параллельных вычислений OpenMP
// (с) Притыкин Д. Е., к.т.н., доцент кафедры "Теоретическая механика"
//
//==============================================================================
#include "openmp_train.h"
const int VEHICLES = 200;
const int N = VEHICLES + 1;
const double c = 1.5e7;
double dt = 1e-7;
double t = 0;
double tk = 10.0;
double m[N]; // массы подвижных единиц (ПЕ)
double y[2*N]; // фазовые координаты ПЕ
double T[N+1]; // усилия в сцепках ПЕ
double F[N]; // вектор внешних сил
double print_time = 0.0;
bool first_print = true;
timeval time0;
timeval time1;
double calc_time = 0;
int i = 0;
int j = 0;
double dT = 0.01;
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void OdeStep(double* mass, double* Y, double* Tc, double* force, double deltaT)
{
#pragma omp for nowait
for (i = 0; i < N; i++)
{
Tc[i+1] = c*(Y[i] - Y[i+1]);
Tc[0] = 0.0;
Tc[N] = 0.0;
Y[i] = Y[i] + Y[i+N]*deltaT;
Y[i+N] = Y[i+N] + deltaT*(force[i] + Tc[i] - Tc[i+1])/mass[i];
}
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int main(void)
{
// Инициализация
m[0] = 129*1000;
F[0] = 450*1000;
for (i = 1; i < N; i++)
{
m[i] = 58*1000;
F[i] = 0.0;
}
for (i = 0; i < 2*N; i++)
{
y[i] = 0.0;
}
for (i = 0; i < N+1; i++)
{
T[i] = 0.0;
}
// Инициализация OpenMP
omp_set_dynamic(0); // Запрещаем менять число потокв при выполнении
omp_set_num_threads(8); // Задаем 8 потоков
// Засекаем время начала расчета
gettimeofday(&time0, NULL);
// Задаем регион кода, вычисляемый параллелльно
#pragma omp parallel shared(m, y, T, F) private(i)
{
while (t <= tk)
{
// Выполняем шаг интегрирования
OdeStep(m, y, T, F, dt);
// Выводим результат на экран
if ( ( t >= dT*j) || (j == 0) )
{
printf("%5i| time: %8.2f, с | progress: %5.1f % | T1: %8.1f, кН\n", j, t, t*100/tk, T[1]/1000.0);
j++;
}
t += dt;
}
}
// Засекаем время окончания расчета
gettimeofday(&time1, NULL);
// Вычисляем время расчета
calc_time = ( time1.tv_sec + time1.tv_usec/1e6 ) - ( time0.tv_sec + time0.tv_usec/1e6 );
printf(" time: %8.2f, с | progress: %5.1f % | T1: %8.1f, кН\n", t, t*100/tk, T[1]/1000.0);
printf("\nCalculation time: %f, s\n", calc_time);
return 0;
}Сабж подключается путем включения в код директив #pragma omp parallel shared(m, y, T, F) private(i) {….} и #pragma omp for nowait, причем последняя, перед циклом, подлежащим распараллеливанию. Распараллеливанию здесь подлежит расчет усилий в сцепках вагонов, расчет ускорений вагонов, и собственно вычесление значения фазовых координат (скорости и перемещения вагонов) на текущем шаге по значениям ускорений и скоростей на предыдущем шаге. То есть это интегрирования самым простецким явным методом Эйлера. Вот функция OdeStep() в данной реализации выполняется параллельно на восьми потоках (хочется сказать ядрах) моего intel core i7. Пришлось покорвырятся, чтобы получить приемлемый результат. Условия расчета такие: время расчета (модельное) - 10 секунд движения поезда, шаг интегрирования - 0.1 микросекунды. Считалось для разного числа вагонов как в параллельном варианте, так и без распараллеливания. Результат - все 8 “ядер” (ну буду я их ядрами звать, проще, знаю я что там 4 ядра с гипертрейдингом…) грузятся на 100% (смотрел по Conky). Производительность расчетов иллюстрирую графиками ![]() С ростом числа решаемых диффур прирост производительности становится всё более существенным :) Видно по синему графику, что с ростом числа диффур время расчета увеличивается крайне незначительно, то есть распараллеливание дает здесь хороший эффект. Конечно, этот код можно ещё оптимизировать, например перейти к расчету сил в упругих связях матричным методом, а операции с матрицами как известно являются хорошо распараллеливаемыми. Ну и деления умножения минимизировать, тоже тут необъятное поля для деятельности… Ок, буду разбираться дальше. P.S.: Ашник не закинул, да там ничего интересного, но все же #pragma once #include <stdio.h> #include <math.h> #include <omp.h> #include <stdlib.h> #include <sys/time.h>
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb http://rusrailsim.org |