Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.74/19: Рейтинг темы: голосов - 19, средняя оценка - 4.74
 Аватар для sigmov
585 / 372 / 63
Регистрация: 22.07.2009
Сообщений: 875
Записей в блоге: 4

Параллельные вычесления

12.02.2011, 06:59. Показов 3972. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня 4x ядерный процессор.
Ну и соответственно, когда я запускаю на своем компе свои программы для математических расчетов, то загружено лишь 25% ЦП.

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

Решил написать тестовое приложение.
Дан длинный массив. К каждому элементу массива прибавить константу (0.1)

Я был в ауте. Расспараллеливание на 2 потока выполнялось в 3 раза медленнее.

Код теста:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
double[] arr = new double[100000000];
int test_count = (int)1e+0;
fixed (double* parr = &arr[0])
{
    DateTime T = DateTime.Now;
    for (int i = 0; i < test_count; i++)
    {
        double* it_f = parr, it_r = it_f + arr.Length - 1;
        while (it_f <= it_r) *(it_f++) += 1;
    }
    Console.WriteLine("Однопоточный: "+(DateTime.Now - T));
    T = DateTime.Now;
    for (int i = 0; i < test_count; i++)
    {
        double* it_f = parr, it_r = it_f + arr.Length - 1;
        //Два потока идут навстречу друг\другу
        Thread one = new Thread(() => { while (it_f < it_r) *(it_f++) += 1; });
        Thread two = new Thread(() => { while (it_f < it_r) *(it_r--) += 1; });
        one.Start();
        two.Start();
        one.Join();
        two.Join();
    }
    Console.WriteLine("Двухпоточный: " + (DateTime.Now - T));
}
Однопоточный: 00:00:00.5703125
Двухпоточный: 00:00:01.5380860

Возможно я неправильно это делаю.... NeedHelp
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.02.2011, 06:59
Ответы с готовыми решениями:

Параллельные вычисления
Здравствуйте! Нужно перебрать целые числа от M до N и найти первое попавшееся число, подходящее под условие. Это просто решить циклом от M...

Параллельные вычисления
Имеется код, который проверяет число j на простоту: using System; using System.Collections.Generic; using System.Linq; using...

Параллельные вычисления на MS Azure - нужен пример
Приветствую, форумчане, есть вопрос. Есть задача, требуюзщая больших вычислительных мощностей, поэтому смотрю в сторону...

3
61 / 61 / 9
Регистрация: 17.02.2010
Сообщений: 101
12.02.2011, 07:53
Цитата Сообщение от sigmov Посмотреть сообщение
У меня 4x ядерный процессор.
Ну и соответственно, когда я запускаю на своем компе свои программы для математических расчетов, то загружено лишь 25% ЦП.

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

Решил написать тестовое приложение.
Дан длинный массив. К каждому элементу массива прибавить константу (0.1)

Я был в ауте. Расспараллеливание на 2 потока выполнялось в 3 раза медленнее.

Код теста:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
double[] arr = new double[100000000];
int test_count = (int)1e+0;
fixed (double* parr = &arr[0])
{
    DateTime T = DateTime.Now;
    for (int i = 0; i < test_count; i++)
    {
        double* it_f = parr, it_r = it_f + arr.Length - 1;
        while (it_f <= it_r) *(it_f++) += 1;
    }
    Console.WriteLine("Однопоточный: "+(DateTime.Now - T));
    T = DateTime.Now;
    for (int i = 0; i < test_count; i++)
    {
        double* it_f = parr, it_r = it_f + arr.Length - 1;
        //Два потока идут навстречу друг\другу
        Thread one = new Thread(() => { while (it_f < it_r) *(it_f++) += 1; });
        Thread two = new Thread(() => { while (it_f < it_r) *(it_r--) += 1; });
        one.Start();
        two.Start();
        one.Join();
        two.Join();
    }
    Console.WriteLine("Двухпоточный: " + (DateTime.Now - T));
}
Однопоточный: 00:00:00.5703125
Двухпоточный: 00:00:01.5380860

Возможно я неправильно это делаю.... NeedHelp
Код у вас конечно ужасный, зачем вам указатели, если вы с таким простым заданием работаете с указателями то зачем вам вообще NET, пишите на C++? Почитайте теорию о параллельном программирование, в вашем случае можно воспользоваться циклом Parallel.For система сама все сделает как нужно, и для измерение скорости нельзя использовать DateTime.Now она очень не точная, лучше хотя-бы использовать Environment.TickCount она возвращает время в милисекундах со старта системы. Вот вам пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static void Main(string[] args)
        {
            var arr = new double[100000000];
            const int testCount = 2;
            var count = Environment.TickCount;
 
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] += testCount;
            }
            Console.WriteLine("Однопоточный: " + (Environment.TickCount - count));
            count = Environment.TickCount;
            Parallel.For(0, arr.Length, i =>
                                            {
                                                arr[i] += testCount;
                                            });
 
            Console.WriteLine("Двухпоточный: " + (Environment.TickCount - count));
 
            Console.ReadLine();
        }
Особого выигрыша в принципе быть и не должно, потому что потоки это тяжелые операции, и использовать их в такой простой задаче не целесообразно, очень советую почитать книги по этой теме.
1
 Аватар для Unril
826 / 717 / 110
Регистрация: 06.10.2010
Сообщений: 825
Записей в блоге: 1
12.02.2011, 10:00
Лучший ответ Сообщение было отмечено как решение

Решение

Вот несколько примеров распараллеливания данной операции:
C#
1
2
3
4
5
6
7
8
9
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
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
 
namespace ConsoleApplicationTest {
    public static class Program {
        private static void Main() {
            var arr = new double[100000000];
            const double testCount = 2.123d;
 
            int count = Environment.TickCount;
            for ( int i = 0; i < arr.Length; i++ ) {
                arr[ i ] += testCount;
            }
            Console.WriteLine( "Однопоточный: " + (Environment.TickCount - count) );
 
            count = Environment.TickCount;
            Parallel.For( 0, arr.Length, i => { arr[ i ] += testCount; } );
            Console.WriteLine( "Parallel: " + (Environment.TickCount - count) );
 
            count = Environment.TickCount;
            ParallelEnumerable.Range( 0, arr.Length ).AsUnordered().ForAll( i => arr[ i ] += testCount );
            Console.WriteLine( "ParallelEnumerable: " + (Environment.TickCount - count) );
 
            count = Environment.TickCount;
            OrderablePartitioner<Tuple<int, int>> rangePartitioner = Partitioner.Create( 0, arr.Length );
            Parallel.ForEach( rangePartitioner,
                              ( range, loopState ) => {
                                  for ( int i = range.Item1; i < range.Item2; i++ ) {
                                      arr[ i ] += testCount;
                                  }
                              } );
            Console.WriteLine( "OrderablePartitioner: " + (Environment.TickCount - count) );
 
            Console.ReadKey();
        }
    }
}
В первом случае - 900
во втором - 600
третий - 450
четвёртый - 230
Процессор черырёхядерный. Как видите, даже такой простой цикл можно очень хорошо распараллелить.
3
 Аватар для sigmov
585 / 372 / 63
Регистрация: 22.07.2009
Сообщений: 875
Записей в блоге: 4
12.02.2011, 15:46  [ТС]
Цитата Сообщение от SPOON Посмотреть сообщение
Код у вас конечно ужасный, зачем вам указатели, если вы с таким простым заданием работаете с указателями то зачем вам вообще NET, пишите на C++?
))) Это был исключительно пример. Согласитесь, что было бы излишне выкладывать сюда 800 строк кода.
Цитата Сообщение от SPOON Посмотреть сообщение
Почитайте теорию о параллельном программирование
Прочитал. И прочитав - решил воспользоваться. )) ((
Цитата Сообщение от SPOON Посмотреть сообщение
в вашем случае можно воспользоваться циклом Parallel.For
К сожалению он доступен ток с NF4.0, мне же нужен движок на 2.0-3.5

Добавлено через 7 минут
Цитата Сообщение от Unril Посмотреть сообщение
Процессор черырёхядерный. Как видите, даже такой простой цикл можно очень хорошо распараллелить.
Опять же NF4.0. Не подходит.
Тем не менее большое спасибо за примеры.

Теперь по-крайней мере буду знать что в 4м обслуживание потоков занимает куда меньше времени.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.02.2011, 15:46
Помогаю со студенческими работами здесь

Параллельные запросы и состояние сеанса
Столкнулся с такой проблемой на проекте: пользователь заходи на один экран, запускает очень долгий процесс. Не дождавшись результата (он по...

Параллельные процессы в c#
Есть задача: читать из таблицы в бд ms SQL некоторую колонку с путями к файлам и копировать их по заданному адресу. Если решать все...

Параллельные вычисления
Нужно использовать параллельные вычисления, при решении данной задачи, пробовал распараллелить циклы, но выдавало не верный результат, код...

Параллельные вычисления с диспетчеризацией потоков
подскажите пожалуйста, как реализовать параллельные вычисления в следующем случае: дано: string str_arr = new string; int...

Статические методы и параллельные потоки
Здравствуйте! Подскажите пожалуйста, статические методы могут выполняться в параллельных потоках или они будут блокироваться?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru