Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 1
Регистрация: 27.12.2014
Сообщений: 298
1

Параллельное программирование - слишком большое ускорение

19.10.2016, 12:19. Показов 873. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Если использовать параллельное программирование, при переходе от 1 потока к 2 потокам возможно ускорение максимум в 2 раза. А у меня при 2 потоках сильно ускорилось. Почему такое могло произойти? Может быть это какой-то turbo boost на процессоре i7-3930k или как?
Вот код функции при заданном числе потоков.
Заметил что такие резкие необъяснимые ускорения происходят только при МАЛЕНЬКИХ картинках. Например, при обработке картинки 60*16 пикселей.
Как можно объяснить такие результаты?
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
      private strParapetresTimeAllSystem getTotalTimeOneThread(Image<Lab, byte> thisImage, string strOnlyfileName, int iThreads, double dAlphaParam = 0)
        {
            //большая структура для возврата
            strParapetresTimeAllSystem BigStruct = new strParapetresTimeAllSystem();
 
            strParapetresTime strForReturnTemp = new strParapetresTime();
 
            double dTimeBinarization = 0;
            double dTimeSegmentation = 0;
            double dTimeAdditional = 0;
            double dTimeGetPirsonForParallel = 0;
            double dAlpha = 0;//для хакона Амдала
 
     
            watchAdditionalTime.Reset();
 
            //src = new Image<Lab, byte>(strFileName);
            watchAdditionalTime.Start();
            listObjectsWork.Add(new MyClass(thisImage, (int)numericUpDownMinObjectSize.Value));
            watchAdditionalTime.Stop();
            Matrix<int> finalClusters = new Matrix<int>(thisImage.Rows * thisImage.Cols, 1);
            //бинаризация
            listObjectsWork[iCountInList].Binarization(checkBoxUsePredobrabotka.Checked);
            dTimeBinarization = listObjectsWork[iCountInList].watchBinarization.Elapsed.TotalSeconds;//время бинаризации
            
            //найти контуры
 
            watchAdditionalTime.Start();
            listObjectsWork[iCountInList].FindCounturs();
            watchAdditionalTime.Stop();
            listObjectsWork[iCountInList].ControlQualityBinarization(iThreads, -1, false);            
            
 
 
            pictureBox2.Image = listObjectsWork[iCountInList].imgBinarized.ToBitmap();
 
 
            if (Directory.Exists(textBoxWorkFolder.Text) == false)
            {
                Directory.CreateDirectory(textBoxWorkFolder.Text);
            }
            if (Directory.Exists(textBoxWorkFolder.Text + strOnlyfileName) == false)
            {
                Directory.CreateDirectory(textBoxWorkFolder.Text + strOnlyfileName);
            }
            //Directory.CreateDirectory(textBoxWorkFolder.Text);
 
            //получить пиксели только объектов
            ParallelOptions options = new ParallelOptions
            {
                MaxDegreeOfParallelism = iThreads
            };
            _iallObjectsCount = listObjectsWork[iCountInList].listRect.Count;
            watchSegments.Reset();
            watchSegments.Start();
            //сегментация
            Parallel.For(0, listObjectsWork[iCountInList].listRect.Count, options, ProcessObjectList);
            watchSegments.Stop();
            for (int aa = 0; aa < listObjectsWork[iCountInList].allObjects.Length; aa++)
            {
                if (listObjectsWork[iCountInList].allObjects[aa] == null)
                {
                    int isdf = 0;
                }
            }
            watchPirson.Reset();
           watchPirson.Start();
           Parallel.For(0, listObjectsWork[iCountInList].listRect.Count, options, GetPirsonForParallel);
            watchPirson.Stop();
 
           try
           {
               string strFolder = textBoxWorkFolder.Text + strOnlyfileName;
               if (checkBoxSeveResults.Checked)
               {
                   for (int index = 0; index < listObjectsWork[iCountInList].listRect.Count; index++)
                   {
                       MyFilesWork.Save_jpg(index, strFolder, listObjectsWork[iCountInList].allObjects[index].imgObject, listObjectsWork[iCountInList].allObjects[index].imgSegmentedObject);
                       MyFilesWork.Save_txt(index, strFolder, listObjectsWork[iCountInList].allObjects[index].detailes.strSegmentsColorsAndS);
                   }
               }
           }
           catch
           {
           }
            dTimeAdditional = watchAdditionalTime.Elapsed.TotalSeconds;
            dTimeSegmentation = watchSegments.Elapsed.TotalSeconds;
            dTimeGetPirsonForParallel = watchPirson.Elapsed.TotalSeconds;
 
            strForReturnTemp.dTime = dTimeAdditional + dTimeSegmentation + dTimeGetPirsonForParallel + dTimeBinarization / _dBinarizationCoefficients[iThreads - 1] + listObjectsWork[iCountInList]._dTimePosledovatelno + listObjectsWork[iCountInList]._dTimeParallel;
            strForReturnTemp.iSize = thisImage.Cols * thisImage.Rows;
            strForReturnTemp.iThreads = iThreads;
            
            //сохранение времени работы всей системы
            BigStruct.allSystemRealTime.dTime = strForReturnTemp.dTime;
            BigStruct.allSystemRealTime.iSize = strForReturnTemp.iSize;
            BigStruct.allSystemRealTime.iThreads = iThreads;
 
            double dAmdals = 0;
 
            //далее следует сохранить время по Амдалсу
            //если 1 поток тогда рассчитываем данные сами
            if (iThreads == 1)
            {
                dAlpha = (dTimeAdditional + listObjectsWork[iCountInList]._dTimePosledovatelno)/ BigStruct.allSystemRealTime.dTime;//доля, которая может быть получена только последовательными вычислениями
                dAmdals = 1.0 / (dAlpha + (1.0 - dAlpha) * 1.0 / iThreads);
                BigStruct.dAlpha = dAlpha;//сохраним значение Альфа
            }
            //если 2 потока тогда на основании существующих данных
            else
            {
                dAlpha = dAlphaParam;
                dAmdals = 1.0 / (dAlpha + (1.0 - dAlpha) * 1.0 / iThreads);
                BigStruct.dAlpha = dAlpha;//сохраним значение Альфа
            }
            BigStruct.allSystemAmdals.dTime = dAmdals;
            BigStruct.allSystemAmdals.iSize = strForReturnTemp.iSize;
            BigStruct.allSystemAmdals.iThreads = iThreads;
            
            //далее сохраним время сегментации
            BigStruct.allSegmentation.dTime = dTimeSegmentation;
            BigStruct.allSegmentation.iSize = strForReturnTemp.iSize;
            BigStruct.allSegmentation.iThreads = iThreads;
 
            //далее сохраним время Пирсона
            BigStruct.allPirson.dTime = dTimeGetPirsonForParallel;
            BigStruct.allPirson.iSize = strForReturnTemp.iSize;
            BigStruct.allPirson.iThreads = iThreads;
 
            ////////////////////////////////////////////////////////////////////////////////////////////////////
            //удалить лишнее - чтобы сократить расходы памяти
            /*listObjectsWork[iCountInList].cannyEdges = null;
            listObjectsWork[iCountInList].imgBinarized = null;
            listObjectsWork[iCountInList].imgSource = null;
            for (int iObj = 0; iObj < listObjectsWork[iCountInList].allObjects.Count; iObj++)
            {
                listObjectsWork[iCountInList].allObjects[iObj].imgObject = null;
                listObjectsWork[iCountInList].allObjects[iObj].imgSegmentedObject = null;
                listObjectsWork[iCountInList].allObjects[iObj].listMatr = null;
            }*/
           //istObjectsWork[iCountInList] = null;
            iCountInList++;
            return BigStruct;
        }
Миниатюры
Параллельное программирование - слишком большое ускорение  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.10.2016, 12:19
Ответы с готовыми решениями:

Слишком большое время работы для маленького цикла
Я реализую алгоритм SURF. Имеется уже заполненная матрица яркостей, где lockBitmap.Width и...

Слишком большое потребление оперативной памяти в простом приложении
Привет. Это простое приложение чтобы делать скриншоты. Скажите почему оно занимает слишком много...

Слишком большое число
При открытии таблиц возникает такая ошибка. В конструкторе в размере поля задано длинное целое.

Слишком большое разрешение экрана
Стояла Vista Premium, пришлось переустановить на Home Basic,сразу после открытия увидела слишком...

2
Администратор
Эксперт .NET
17583 / 13802 / 5302
Регистрация: 17.03.2014
Сообщений: 28,285
Записей в блоге: 1
19.10.2016, 12:36 2
Dimarik__1, при небольших объемах вычислений возрастает погрешность измерения. Думаю причина в этом.
0
Эксперт .NET
17791 / 12942 / 3381
Регистрация: 17.09.2011
Сообщений: 21,216
19.10.2016, 12:42 3
Цитата Сообщение от Dimarik__1 Посмотреть сообщение
Как можно объяснить такие результаты?
Как правило, такие результаты объясняются неправильно выбранной методикой замера времени.
Вот вы, к примеру, запустили один и тот же код сначала синхронно, а потом параллельно; и всё в пределах одного метода и запуска.
А вы учли влияние на второй тест сборщика из-за мусора, оставленного первым тестом?
А работу джиттера, который компилирует код при первом запуске?
А при замерах вы замеряете только то, что уникально для определенного теста или всё подряд (например, создание объектов)?
И так далее.

В код особо не вникал, потому не гарантирую, что вышеперечисленное у вас обязательно встречается, но это вещи, на которые стоит обратить внимание при сравнении производительности.
2
19.10.2016, 12:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.10.2016, 12:42
Помогаю со студенческими работами здесь

Слишком большое число циклов for
Здравствуйте! Столкнулся со следующей проблемой: появилась необходимость расчета большого числа...

Слишком большое разрешение экрана
Здравствуйте. Помогите пожалуйста с проблемой. Имеется ноутбук с диагональю 17.3 дюйма и...

Ttfb время слишком большое
Здравствуйте. Кто-нибудь знает, почему ttfb время слишком большое? От чего это бывает и как...

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


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru