Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
 Аватар для mustcl
22 / 22 / 22
Регистрация: 15.05.2011
Сообщений: 69

Вычисление в цикле

28.08.2011, 20:53. Показов 3233. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. У меня в цикле производятся вычисления(около 3 минут). и при этом задействовано только 1 ядро(из 4) т.е. весь комп на 25%. Можно как нибудь задействовать все 4 ядра? Чтобы вычисления шли не 3 минуты, а хотя бы 1мин.?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.08.2011, 20:53
Ответы с готовыми решениями:

Вычисление выражения в цикле
Дано уравнение y=sqrt(2+n)/x^(1+m) которое увеличивается n=1 a m=2 for (int q = 1; q <= 18; q++) for...

Вычисление значения в цикле
Помогите написать код по условию. 1. Ввести с консоли два числа a и b 2.Сравнить значение переменной b со значением переменной d...

Вычисление выражения в одном цикле
Дано действительное число x. Вычислить ((x-2)(x-4)(x-8)…(x-256))/((x-1)(x-3)(x-7)…(x-255)) . Здесь должен быть один цикл. Как это...

8
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
28.08.2011, 21:31
- разделить вычисления на несколько циклов никак ?
- какие вычисления ?
ваш вопрос слишком "теоретический", что предполагат такой же "теоретический" ответ: можно
1
 Аватар для mustcl
22 / 22 / 22
Регистрация: 15.05.2011
Сообщений: 69
28.08.2011, 21:53  [ТС]
тут даже можно сказать не вычисления а сравнения.
Есть два Memo в 1ом (100000 строк) в 2ом (20000 строк) и нужно каждую сточку первого Memo сравнить с каждой строчкой второго Memo.... вот надо этот процесс ускорить как можно быстрее.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
28.08.2011, 22:48
запустить сразу несколько циклов и посмотреть
C++
1
2
3
4
5
6
7
8
9
10
11
int i = 0;
while  (i < 10000) {
//  ...
  i++;
}
int i = 10001;
while  (i < 20000) {
//  ...
  i++;
}
// и т.д.
Добавлено через 17 минут
Эта цитата (поскольку ссылки на форумы низзя) - пример того, что если поискать - то можно найти , ведь все уже украдено до нас
Processor - Выполнение процедур на многопроцессорных ВС. Распараллеливание

Нужно выполнить процедуру сортировки ( да в принципе не важно какую) на многопроцессорной машине. Естественноно нужно распараллелить ее на несколько процессов , чтобы каждый проц выполнял свой процес(поток), чтобы выжать из системы максимум.
А вот как определить сколько ядер на машине не знаю.
Может кто подскажет чего-нибудь по теме?

А тебе это надо? Зачем привязываться к количеству ядер/процессоров?

Мне Нужно создать класс ,сортирующий массив, который бы создавал n (n-число процессоров) процессов, каждый из который бы работал только с куском массива передаваемым ему как параметр.

Каким образом можно создавать потоки в своём классе ?

http://www.microsoft.com/techn... x?mfr=true
SetThreadAffinityMask

Я бы посоветовал создавать не процессы а потоки и потом уже в зависимости от числа процессоров в системе распеределятьих непосредственно на разные процессоры... Хотя можно и процессы.. только тогда придётся организовывать межпроцессной взаимодействие.. нампример через Shared Memory...

Вы только учтите сразу что Борляндовский менеджер памяти ОЧЕНЬ не дружит с многопроцессорностью и потенциально Вы можете получить замедление работы а не выигрыш по скорости. Хотя конечно это сильно зависит от того как Вы организуете Ваши структуры данных...

Можно ли использовать функцию CreateThread() и как для создания потока?

Примерная структура класса:
C++
1
2
3
4
5
6
7
8
9
10
11
class Parallel{
   int n;  //chislo potokov
   public:
     Parallel(){n=0;};
     My *Potok[16];
     void add_potok();
     int *Run(int *mas,int n_mas);
                  };
void Parallel::add_potok(){
    Potok[n]=CreateThread(/*   какой использовать параметр ?   */);
    n++;
Можно ли использовать функцию CreateThread() и как для создания потока?

Функция CreateThread


Мы уже говорили, как при вызове функции CreateProcess появляется на свет первичный поток процесса. Если Вы хотите создать дополнительные потоки, нужно вызывать из первичного потока функцию CreateThread:
C++
1
2
3
4
5
6
7
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
DWORD cbStack,
PTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD fdwCreate,
PDWORD pdwThreadID);
При каждом вызове этой функции система создает объект ядра "поток". Это не сам поток, а компактная структура данных, которая используется операционной системой для управления потоком и хранит статистическую информацию о потоке. Так что объект ядра "поток" — полный аналог объекта ядра "процесс".

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

NOTE:
--------------------------------------------------------------------------------
CreateThread - это Windows-функция, создающая поток. Но никогда не вызывайте ее, если Вы пишете код на С/С++. Вместо нее Вы должны использовать функцию _beginthreadex из библиотеки Visual С++. (Если Вы работаете с другим компилятором, он должен поддерживать свой эквивалент функции CreateThread). Что именно делает _beginthreadex и почему это так важно, я объясню потом.
О'кэй, общее представление о функции CreateThread Вы получили. Давайте рассмотрим все ее параметры.

Параметр psa
Параметр psa является указателем на структуру SECURITY_ATTRIBUTES. Если Вы хотите, чтобы объекту ядра "поток" были присвоены атрибуты защиты по умолчанию (что чаще всего и бывает), передайте в этом параметре NULL. A чтобы дочерние процессы смогли наследовать описатель этого объекта, определите структуру SECURITY_ATTRIBUTES и инициализируйте ее элемент bInheritHandle значением TRUE (см. главу 3).

Параметр cbStack
Этот параметр определяет, какую часть адресного пространства поток сможет использовать под свой стек. Каждому потоку выделяется отдельный стек. Функция CreateProcess, запуская приложение, вызывает CreateThread, и та инициализирует первичный поток процесса. При этом CreateProcess заносит в параметр cbStack значение, хранящееся в самом исполняемом файле. Управлять этим значением позволяет ключ /STACK компоновщика:

/STACK.[reserve][,commit]

Аргумент reserve определяет объем адресного пространства, который система должна зарезервировать под стек потока (по умолчанию — 1 Мб). Аргумент commit задает объем физической памяти, который изначально передается области, зарезервированной под стек (по умолчанию — 1 страница). По мере исполнения кода в потоке Вам, весьма вероятно, понадобится отвести под стек больше одной страницы памяти. При переполнении стека возникнет исключение. (О стеке потока и исключениях, связанных с его переполнением, см. главу 16, а об общих принципах обработки исключений — главу 23.) Перехватив это исключение, система передаст зарезервированному пространству еще одну страницу (или столько, сколько указано в аргументе commit). Такой механизм позволяет динамически увеличивать размер стека лишь по необходимости.

Если Вы, обращаясь к CreateThread, передаете в параметре cbStack ненулевое значение, функция резервирует всю указанную Вами память. Ее объем определяется либо значением параметра cbStack, либо значением, заданным в ключе /STACK компоновщика (выбирается большее из них). Но передается стеку лишь тот объем памяти, который соответствует значению в cbStack. Если же Вы передаете в параметре cbStack нулевое значение, CreateThread создает стек для нового потока, используя информацию, встроенную компоновщиком в EXE-файл.

Значение аргумента reserve устанавливает верхний предел для стека, и это ограничение позволяет прекращать деятельность функций с бесконечной рекурсией. Допустим, Вы пишете функцию, которая рекурсивно вызывает сама себя. Предположим также, что в функции есть "жучок", приводящий к бесконечной рекурсии. Всякий раз, когда функция вызывает сама себя, в стеке создается новый стековый фрейм. Если бы система не позволяла ограничивать максимальный размер стека, рекурсивная функция так и вызывала бы сама себя до бесконечности, а стек поглотил бы все адресное пространство процесса. Задавая же определенный предел, Вы, во-первых, предотвращаете разрастание стека до гигантских объемов и, во-вторых, гораздо быстрее узнаете о наличии ошибки в своей программе. (Программа-пример Summation в главе 16 продемонстрирует, как перехватывать и обрабатывать переполнение стека в приложениях.)

Параметры pfnStartAddr и pvParam
Параметр pfnStartAddr определяет адрес функции потока, с которой должен будет начать работу создаваемый поток, а параметр pvParam идентичен параметру pvParam функции потока. CreateThread лишь передает этот параметр по эстафете той функции, с которой начинается выполнение создаваемого потока. Таким образом, данный параметр позволяет передавать функции потока какое-либо инициализирующее значение. Оно может быть или просто числовым значением, или указателем на структуру данных с дополнительной информацией.

Вполне допустимо и даже полезно создавать несколько потоков, у которых в качестве входной точки используется адрес одной и той же функции. Например, можно реализовать Web-сервер, который обрабатывает каждый клиентский запрос в отдельном потоке. При создании каждому потоку передается свое значение pvParam.

Учтите, что Windows — операционная система с вытесняющей многозадачностью, а следовательно, новый поток и поток, вызвавший CreateThread, могут выполняться одновременно. В связи с этим возможны проблемы. Остерегайтесь, например, такого кода.
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
DWORD WINAPI FirstThread(PVOID pvParam)
{
// инициализируем переменную, которая содержится в стеке
int x = 0;
 
DWORD dwThreadId;
 
// создаем новый поток
HANDLE hThread = CreateThread(NULL, 0, SecondThread,
(PVOID) &x, 0, &dwThreadId);
 
// мы больше не ссылаемся на новый поток,
// поэтому закрываем свой описатель этого потока
CloseHandle(hThread);
 
// Наш поток закончил работу.
 
// ОШИБКА, его стек будет разрушен, но SecondThread
// может попытаться обратиться к нему
 
return(0);
}
 
DWORD WINAPI SecondThread(PVOID pvParam)
{
// здесь выполняется какая-то длительная обработка
 
// Пытаемся обратиться к переменной в стеке FirstThread,
// ПРИМЕЧАНИЕ - это может привести к ошибке общей защиты:
// нарушению доступа
* ((int *) pvParam) = 5;
return(0);
}
Не исключено, что в приведенном коде FirstThread закончит свою работу до того, как SecondThread присвоит значение 5 переменной x из FirstThread. Если так и будет, SecondThread не узнает, что FirstThread больше не существует, и попытается изменить содержимое какого-то участка памяти с недействительным теперь адресом. Это неизбежно вызовет нарушение доступа: стек первого потока уничтожен по завершенииFirstThread. Что же делать? Можно объявить x статической переменной, и компилятор отведет память для хранения переменной x не в стеке, а в разделе данных приложения (application's data section). Но тогда функция станет нереентерабельной. Иначе говоря, в этом случае Вы не смогли бы создать два потока, выполняющих одну и ту же функцию, так как оба потока совместно использовали бы статическую переменную. Другое решение этой проблемы (и его более сложные варианты) базируется на методах синхронизации потоков, речь о которых пойдет в главах 8, 9 и 10.

Параметр fdwCreate
Этот параметр определяет дополнительные флаги, управляющие созданием потока. Он принимает одно из двух значений. 0 (исполнение потока начинается немедленно) или CREATE_SUSPENDED. В последнем случае система создает поток, инициализирует его и приостанавливает до последующих указаний.

Флаг CREATE_SUSPENDED позволяет программе изменить какие-либо свойства потока перед тем, как он начнет выполнять код. Правда, необходимость в этом возникает довольно редко. Одно из применений этого флага демонстрирует программа - пример JobLab из главы 5.

Параметр pdwThreadID
Последний параметр функции CreateThread - это адрес переменной типа DWORD, в которой функция возвращает идентификатор, приписанный системой новому потоку. (Идентификаторы процессов и потоков рассматривались в главе 4.)

NOTE:
--------------------------------------------------------------------------------
В Windows 2000 и Windows NT 4 в этом параметре можно передавать NULL (обычно так и делается). Тем самым Вы сообщаете функции, что Вас не интересует идентификатор потока. Но в Windows 95/98 это приведет к ошибке, так как функция попытается записать идентификатор потока по нулевому адресу, что недопустимо. И поток не будет создан.
Такое несоответствие между операционными системами может создать разработчикам приложений массу проблем. Допустим, Вы пишете и тестируете программу в Windows 2000 (которая создает поток, даже если Вы передаете NULL в pdwThreadID). Но вот Вы запускаете приложение в Windows 98, и функция CreateThread, естественно, дает ошибку. Вывод один: тщательно тестируйте свое приложение во всех операционных системах, в которых оно будет работать.

В этой книжке написано:
Цитата:

параметр pvParam идентичен параметру pvParam функции потока

а про этот параметр в функции потока в этой же книжке говорится следующее:
Цитата:

Система обращается к Вашей функции, передавая ей 32-битный параметр lpvThreadParm, который Вы ранее передали CreateThread.

Может кто-нить объяснит, что там должно передаваться?

Правда, еще в 4м издании книги есть такое:

функциям потоков передается единственный параметр, смысл которого определяется Вами, а не операционной системой

т.е. если я хочу в функцию потока передать какие-то свои собственные любые данные, я могу сделать это с пом. этого параметра?

Да, при помощи pvParam можно передавать данные потокам.
да, забыл - количество процессоров:
Processor - NUMBER_OF_PROCESSORS

http://technet.microsoft.com/r... us%29.aspx

HKLM\SYSTEM\CurrentControlSet\Control\Se ssion Manager\Environment

Data type
REG_SZ

Range
1–32 (in decimal)

Default value
For Windows 2000 Server: 4 For Windows 2000 Professional: 2 For Windows 9x and Millennium: 1

Description

Stores the number of processors installed on the computer.
1
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
29.08.2011, 09:12
Все вычисления можно выполнить за 100мс или меньше, не прибегая к распараллеливанию
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
29.08.2011, 14:23
kzru_hunter, ответ хорош примером .
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
29.08.2011, 15:14
Ок На моем ноуте результат где-то ~95мс
Вложения
Тип файла: rar MemoDiff.rar (24.5 Кб, 47 просмотров)
2
 Аватар для SalterOk
117 / 114 / 10
Регистрация: 02.06.2011
Сообщений: 280
29.08.2011, 15:20

Не по теме:

примера не последовало;)


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

Добавлено через 2 минуты
kzru_hunter, прошу прощения - когда писал не видел твоего поста.
Щас посмотрим...
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
29.08.2011, 15:44
Там используется функция array_string_compare, которая как раз и сравнивает массивы.
Есть ошибка в коде при вызове этой функции:
array_string_compare(sArray1, iCount1, sArray2, iCount2, sArray3, 1)
последний параметр в этой функции - означает, как нужно сравнить массивы:
0 - означает найти разность: массив1 - массив21
1 - означает найти симметрич. разность: (массив1 - массив2) + (массив2 - массив1)
2 - означает найти объединение значений массивов
3 - означает найти пересечение значений массивов

для массивов 100000x20000 время оказалось немного больше: 350-600мс
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.08.2011, 15:44
Помогаю со студенческими работами здесь

Ошибка в итерационном цикле (Вычисление числа Пи)
Доброго времени суток, ув. форумчане! Откройте, пожалуйста, глаза, ибо уже битый час &quot;бьюсь&quot; над поиском ошибки. ...

Вычисление суммы заказа в одном цикле
Задача: Вычислить текущюю сумма заказа в покупательской корзине (в одном цикле) ... &lt;li class=&quot;mcart-item&quot;&gt;&lt;span...

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

Как програмно в цикле не доходя до конца, пропустить шаг в цикле?
Как програмно в цикле не доходя до конца, пропустить шаг в цикле?

При склеивании строк в цикле, уже на пятом цикле возникает переполнение памяти
При склеивании строк в цикле, уже на пятом цикле возникает переполнение памяти. Что не так и как правильно сделать? Не пинайте нуба! ...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru