2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3  След.
 
 visual studio 200X многопоточность С#
Сообщение29.10.2015, 13:53 
Аватара пользователя


30/03/10
51
Добрый день товарищи, недавно столкнулся с такой проблемой - и хотелось бы попросить помощи:
Что такое многопоточные вычисления я знаю, но вот про применение тут заминка...
так вот вопросы возникают такого плана:
Допустим у нас есть вычисления массивов:
Код:
for(int ix = 1 ; ix<=Nx; ix++){
             for(int iy = 1 ; iy<=Ny; iy++){
                //------------- делаем тут что то----------------
                //-------------------------------------------------
                                                          }
                                              }

for(int ix = 1 ; ix<=Nz; ix++){
             for(int iy = 1 ; iy<=Nd; iy++){
                //------------- делаем тут что то----------------
                //-------------------------------------------------
                                                          }
                                              }

так вот после компиляции - как я понимаю и запуске будет выполняться строго последовательно вычисление по первому массиву Nx-Ny, а после вычислений по Nz-Nd...
1) так или не так товарищи?
1.1)если так - (последовательно)то возникает вопрос, а как скажем отправить вычисления в два потока?
1.2) если нет -(потоки) - то ОС берёт на себя разделения на потоки(сильно сомневаюсь тут).

2) если потоки нужно задавать самому то поделитесь примерами пожалуйста.
3) подкиньте литературу - пожалуйста по данной тематике...

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение29.10.2015, 13:58 
Заслуженный участник


04/03/09
910
gdoom в сообщении #1068022 писал(а):
так или не так товарищи?

Так.
gdoom в сообщении #1068022 писал(а):
а как скажем отправить вычисления в два потока?

Пример: http://habrahabr.ru/post/126495/

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение29.10.2015, 14:10 
Аватара пользователя


30/03/10
51
12d3 в сообщении #1068024 писал(а):
gdoom в сообщении #1068022 писал(а):
так или не так товарищи?

Так.
gdoom в сообщении #1068022 писал(а):
а как скажем отправить вычисления в два потока?

Пример: http://habrahabr.ru/post/126495/


спасибо большое!

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение29.10.2015, 16:34 
Аватара пользователя


30/03/10
51
Спасибо, начинается всё более укладываться но вот вопрос, уже непосредственно по реализации - вот кусок:
Код:
public partial class Form1 : Form
    {
        int Ft;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //создаем 4 потока, в качестве параметров передаем имя Выполняемой функции
            Thread th_1 = new Thread(CalcZ);
            Thread th_2 = new Thread(CalcZ);
            Thread th_3 = new Thread(CalcZ);
            Thread th_4 = new Thread(CalcZ);
            //расставляем приоритеты для потоков
            th_1.Priority = ThreadPriority.Highest; // самый высокий
            th_2.Priority = ThreadPriority.BelowNormal; // выше среднего
            th_3.Priority = ThreadPriority.Normal; // средний
            th_4.Priority = ThreadPriority.Lowest; // низкий
            // запускаем каждый поток
            th_1.Start();
            th_2.Start();
            th_3.Start();
            th_4.Start();
            //Ждем заврешения каждого потока
            th_1.Join();
            th_2.Join();
            th_3.Join();
            th_4.Join();
        }

        static void CalcZ()
        {
            int N = 50000;
            double z;
            z = 0;
            for (int i = 1; i <= N; i++)
            {
                for (int j = 1; j <= N; j++)
                {
                    z++;
                    z = System.Math.Cos(z);
                }
            }
         
        }       

    }

допустим по окончанию потоков скажем нужно передать в массивы:
Код:
double[] mos_1 = new double[....];
double[] mos_2 = new double[....];
double[] mos_3 = new double[....];
double[] mos_4 = new double[....];


полученные значения. Как это сделать - ведь в
Код:
static void CalcZ()
        {
            int N = 50000;
            double z;
            z = 0;
            for (int i = 1; i <= N; i++)
            {
                for (int j = 1; j <= N; j++)
                {
                    z++;
                    z = System.Math.Cos(z);
                }
            }
         
        }       


их просто не видит, или я не умею к ним обращаться. Вопрос дилетанта, но просто не знаю - вот и спрашиваю....

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение29.10.2015, 17:05 
Заслуженный участник


04/03/09
910
Например так:
Код:
double[] mos_1;
Thread th_1 = new Thread(() => CalcZ(out mos_1));
th_1.Start();

А функция теперь будет с параметром.
Код:
static void CalcZ(out double[] m)
        {
        //тут инициализируете и заполняете массив
         
        }   

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение29.10.2015, 17:07 
Заслуженный участник


20/08/14
11780
Россия, Москва
При старте потока ему передаётся его номер, по которому он определяет в какой массив ему писать результаты. Вероятно можно передать сразу указатель на массив ...

-- 29.10.2015, 17:10 --

Не, я бы передавал при старте, а не при создании - можно будет одним потоком обрабатывать несколько массивов - меньше накладных расходов.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение30.10.2015, 10:40 
Аватара пользователя


30/03/10
51
12d3 в сообщении #1068099 писал(а):
Например так:
Код:
double[] mos_1;
Thread th_1 = new Thread(() => CalcZ(out mos_1));
th_1.Start();

А функция теперь будет с параметром.
Код:
static void CalcZ(out double[] m)
        {
        //тут инициализируете и заполняете массив
         
        }   

Dmitriy40 в сообщении #1068102 писал(а):
При старте потока ему передаётся его номер, по которому он определяет в какой массив ему писать результаты. Вероятно можно передать сразу указатель на массив ...

-- 29.10.2015, 17:10 --

Не, я бы передавал при старте, а не при создании - можно будет одним потоком обрабатывать несколько массивов - меньше накладных расходов.

Спасибо Товарищи! помогло! Смог справится - но как обычно выскакивает проблема дальше. Вновь воткну код:

Код:
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        int Ft;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //создаем 4 потока, в качестве параметров передаем имя Выполняемой функции
            double[] mos_1 = new double[1000];
            double[] mos_2 = new double[1000];
            double[] mos_3 = new double[1000];
            double[] mos_4 = new double[1000];
            Thread th_1 = new Thread(() => CalcZ(mos_1));
            Thread th_2 = new Thread(() => CalcZ(mos_2));
            Thread th_3 = new Thread(() => CalcZ(mos_3));
            Thread th_4 = new Thread(() => CalcZ(mos_4));
            //расставляем приоритеты для потоков
            th_1.Priority = ThreadPriority.Highest; // самый высокий
            //th_2.Priority = ThreadPriority.BelowNormal; // выше среднего
            th_2.Priority = ThreadPriority.BelowNormal;
            //th_3.Priority = ThreadPriority.Normal; // средний
            th_3.Priority = ThreadPriority.BelowNormal;
            //th_4.Priority = ThreadPriority.Lowest; // низкий
            th_4.Priority = ThreadPriority.BelowNormal;
            // запускаем каждый поток
            th_1.Start();
            th_2.Start();
            th_3.Start();
            th_4.Start();
            //Ждем заврешения каждого потока
            th_1.Join();
            th_2.Join();
            th_3.Join();
            th_4.Join();

            //for (int i = 1; i <= 10; i++) textBox1.Text = textBox1.Text + System.Convert.ToString(mos_1[i])+"\r\n";
        }

        static void CalcZ(double[] m)
        {
            int N = 90000000;
            double z;
            z = 0;
            for (int i = 1; i <= N; i++)
                for (int j = 1; j <= N; j++)
                {
                    z++;
                z = System.Math.Cos(z*180/3.14);

                //m[i] = z;
            }
         
        }       

    }
}


как видите int N = 90000000; и процесс умирает страшно т.к число вычислений $3.24 \cdot 10^{16}$ вычислений, просто это как раз тот минимум который мне требуется для расчётов. Возникли вопросы такого плана:
1) можно ли больше нарезать потоков?
2) помогите пожалуйста или толкните, как можно ещё оптимизировать код в данном выше примере, конечно это не конкретно к моей задачи - просто так будет ясно, как двигаться...
3) следует ли переходить на указатели - то есть непосредственно работать с оперативной памятью(как я помню в c++ builder я сам непосредственно создавал указатели и массив в памяти и после работы с ним выпиливал его ручками) - (опять же даст ли это прирост скорости вычислений)

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение30.10.2015, 12:53 
Заслуженный участник


20/08/14
11780
Россия, Москва
Потоков можно запустить сколько угодно (тысячи - точно можно), но если их больше количества ядер процессора, то общего ускорения уже не будет.

Я ошибаюсь или все 4 потока вычисляют ровно одно и тоже? Т.к. никак не зависят от номера потока.

При таком количестве вычислений экономия десятка тактов на замене индекса на указатель никакой роли не играет.

Ну и количество операций посчитано очень грубо, на самом деле их на порядок больше - в косинусе. Косинус вычисляется примерно за 50-150 тактов, на 4 ядра, на $10^{16}$ итераций и на частоте 4ГГц это от года до трёх непрерывного счёта. Надо подумать зачем столько разных косинусов, может можно по табличкам их определять, или вдруг они периодичны ...
Т.е. оптимизировать надо не код, а сначала алгоритм. Оптимизировать же старт и ожидание завершения потоков смысла нет.

PS. А что, операция ++ стала разрешена для вещественных типов?! :shock:

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение30.10.2015, 13:11 
Аватара пользователя


30/03/10
51
Dmitriy40 в сообщении #1068397 писал(а):
Потоков можно запустить сколько угодно (тысячи - точно можно), но если их больше количества ядер процессора, то общего ускорения уже не будет.

вот тут интересно, как же к примеру решает проблему в пакетах open_foam или ansys......

Dmitriy40 в сообщении #1068397 писал(а):
Я ошибаюсь или все 4 потока вычисляют ровно одно и тоже? Т.к. никак не зависят от номера потока.

да это просто шаблон грубый на котором исследую они считают одно и то же все....

Dmitriy40 в сообщении #1068397 писал(а):
Ну и количество операций посчитано очень грубо, на самом деле их на порядок больше - в косинусе. Косинус вычисляется примерно за 50-150 тактов, на 4 ядра, на $10^{16}$ итераций и на частоте 4ГГц это от года до трёх непрерывного счёта. Надо подумать зачем столько разных косинусов, может можно по табличкам их определять, или вдруг они периодичны ...


косинус это только цветочки
$q:\to ({{p_f}^2-{p_{f+1}}^2}/{R T z})^{1/2}$
как думаете сколько нагрузит такое уравнение и при этом их будет порядка N, N>10 :facepalm:
Буду рад советам товарищи, вопрос довольно непростой - по крайней мере для меня....

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение30.10.2015, 13:26 
Заслуженный участник


04/03/09
910
Рекомендую вам привести полностью задачу, которую вы хотите решить, авось, придумается гораздо более быстрый алгоритм.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение01.11.2015, 12:27 


11/12/14
893
gdoom в сообщении #1068402 писал(а):
вот тут интересно, как же к примеру решает проблему в пакетах open_foam или ansys......


Как таковой проблемы тут нет. Environment.ProcessorCount содержит число логических процессоров. Для интенсивных вычислений не имеет смысла создавать больше потоков, чем содержится в этом свойстве.
Есть еще другая ниша - вычисления на GPU. CUDA или OpenCL. Производительность может в десятки раз обгонять вычисления на CPU. Но там много больше возни и надо чтобы задача хорошо ложилась на распараллеливание вычислений.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 06:24 
Аватара пользователя


30/03/10
51
aa_dav в сообщении #1069095 писал(а):
gdoom в сообщении #1068402 писал(а):
вот тут интересно, как же к примеру решает проблему в пакетах open_foam или ansys......


Как таковой проблемы тут нет. Environment.ProcessorCount содержит число логических процессоров. Для интенсивных вычислений не имеет смысла создавать больше потоков, чем содержится в этом свойстве.
Есть еще другая ниша - вычисления на GPU. CUDA или OpenCL. Производительность может в десятки раз обгонять вычисления на CPU. Но там много больше возни и надо чтобы задача хорошо ложилась на распараллеливание вычислений.


я так понимаю предлагаете задействовать ресурсы видеокарты?

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 06:42 
Заслуженный участник


20/08/14
11780
Россия, Москва
Предполагаю видеокарта кардинально проблему не решит: не умеет она быстро считать сложные функции (типа косинуса), каждая будет раскладываться в ряды, что на порядок-два увеличит общее количество операций. И хотя она конечно в сотни и тысячи раз быстрее их выполнит, но вместо лет счёта получим всего лишь месяцы. Хотя конечно надо проверять, я понятия не имею как правдоподобно теоретически оценить скорость вычисления на видеокарте, цифры пиковой вычислительной мощности тут прямо не применишь.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 06:54 
Заслуженный участник


27/04/09
28128
gdoom
Пожалуйста, следующий код помещайте лучше в тег syntax, а не code — там есть подсветка синтаксиса. Его можно вставить, выбрав C# из списка «Подсветка синтаксиса» над полем ввода.

Кстати, если у вас в рабочем коде такое же четырёхкратное повторение как в последнем отрывке, лучше завести массивы/списки соответственно потоков, массивов и всего связанного и делать инициализацию в цикле и запуск (в том же или другом) — тоже. Заодно сможете делать не 4, а другое число потоков.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 07:00 
Аватара пользователя


30/03/10
51
Dmitriy40 в сообщении #1069442 писал(а):
Предполагаю видеокарта кардинально проблему не решит: не умеет она быстро считать сложные функции (типа косинуса), каждая будет раскладываться в ряды, что на порядок-два увеличит общее количество операций. И хотя она конечно в сотни и тысячи раз быстрее их выполнит, но вместо лет счёта получим всего лишь месяцы. Хотя конечно надо проверять, я понятия не имею как правдоподобно теоретически оценить скорость вычисления на видеокарте, цифры пиковой вычислительной мощности тут прямо не применишь.


ну да я уже начала изучать посты :
http://habrahabr.ru/post/72247/
https://toster.ru/q/18810
- уже выпал в небольшой осадок :shock: - понял, что пора запастись энергетиком :| и штурмовать теорию.... А насчёт вычисления, думаю в начале нужно разобраться как именно пилить вычисления под GPU хотелось бы под GLSL но думаю не прокатит, в начале лучше OpenCL или CUDA - я пока только начал разбираться в данной теме :facepalm:

-- Пн ноя 02, 2015 08:03:47 --

arseniiv в сообщении #1069444 писал(а):
gdoom
Пожалуйста, следующий код помещайте лучше в тег syntax, а не code — там есть подсветка синтаксиса. Его можно вставить, выбрав C# из списка «Подсветка синтаксиса» над полем ввода.

- спасибо большое учту далее, как немного разберусь)
arseniiv в сообщении #1069444 писал(а):
gdoom
Кстати, если у вас в рабочем коде такое же четырёхкратное повторение как в последнем отрывке, лучше завести массивы/списки соответственно потоков, массивов и всего связанного и делать инициализацию в цикле и запуск (в том же или другом) — тоже. Заодно сможете делать не 4, а другое число потоков.

- да я так и собирался, пораскинув в выходные дни, но опять же маловато производительности.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу 1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group