Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
C++IDEНовости

C ++ Builder; Общие библиотеки (библиотека времени выполнения), библиотека параллельного программирования.

C ++ Builder обеспечивает три уровня разработки:
1. Компоненты (VCL и FMX)
2. Общие библиотеки (RTL).
3. API платформы (iOS, Android, Mac OS)


В этом посте мы обсудим общие библиотеки (RTL).

В C ++ Builder есть несколько сотен функций, макросов и классов, которые вы вызываете из своих программ на C и C ++ для выполнения широкого спектра задач, включая низко- и высокоуровневый ввод-вывод, манипулирование строками и файлами, выделение памяти, управление процессами. , преобразование данных, математические вычисления и многое другое.

Библиотека времени выполнения C ++ Builder (или RTL) состоит из ряда базовых файлов заголовков, которые обеспечивают базовую поддержку для большинства библиотек компонентов VCL и FireMonkey. РТЛ включает в себя процедуры, глобальные вспомогательные классы , такие как те , которые представляют собой потоки и списки, а также классы , такие как TObject, TPersistent и TComponent.

Несмотря на то, тесно связана с FireMonkey и VCL, то РТЛ не включает в себя какой — либо из компонентов , которые появляются на Палитра инструментов.

Вместо этого, классы и процедуры в RTL используются компоненты , которые делают появляются на палитре инструментов, и доступны для использования в коде приложения либо в VCL или проекты FireMonkey, или когда вы пишете свои собственные классы.

Например, заголовок System содержит большую часть библиотеки времени выполнения (RTL). Взаимодействие с другими людьми

И из заголовка системы, у вас есть System.Math.hpp заголовок , который определяет классы, процедуры, типы, переменные и константы , связанные с математическими операциями, векторами и матрицами.

Или System.Bluetooth.hpp заголовок , который предоставляет классы для использования возможности Bluetooth устройства, на котором выполняется приложение для подключения к приложениям , работающим на удаленных устройствах.

или System.Sensors.hpp заголовок , который обеспечивает классы и компоненты , которые позволяют получать информацию и управлять датчиками системы. Датчики , являются частями оборудования или программного обеспечения , которые могут обеспечить меры физических величин для ваших приложений.

Или System.Threading.hppзаголовок , который определяет классы и типы , которые реализуют в параллельную библиотеку программирования.

Давайте теперь посмотрим на примере C ++ Builder с использованием System.Threading.hpp заголовка и параллельного программирования библиотеки.

Для моего примера приложения, я буду использовать C ++ Builder 10.4 приложение проекта, которое использует общую библиотеку времени выполнения в приложении для нескольких устройств, используя заголовок RTL System.Threading и библиотеку параллельного программирования.

Вы можете скачать этот образец приложения проекта TParallelPrime.cbproj здесь.

ui-4

Вот приложение проекта C ++ Builder, которое использует общую библиотеку времени выполнения в приложении для нескольких устройств, используя заголовок RTL System.Threading и библиотеку параллельного программирования.

#include <System.Threading.hpp>    // TParallel::For
#include <System.Diagnostics.hpp>  // System::Diagnostics::TStopwatch
#include <System.SyncObjs.hpp>     // TInterlocked::Increment

В этом примере показано, как использовать метод TParallel.For из библиотеки параллельного программирования (PPL) . TParallel.For разбивает цикл for на части, которые выполняются параллельно, и использует задачи для выполнения этих частей.

Это приложение находит количество простых чисел от 1 до максимального значения, например 5 миллионов в этом приложении. Приложение рассчитает время, необходимое для этого, используя (1) классический цикл for, и мы сделаем то же самое, используя параллельную версию, используя метод TParallel.For.

В пользовательском интерфейсе приложений:

Кнопка «Для цикла» запустит серийную версию расчета простых чисе

// Button event handler that finds prime numbers using the classic for loop
void __fastcall TForm2::btnForLoopClick(TObject *Sender) {
	int Max = 5000000; // 5 Million
	Tot = 0;
	System::Diagnostics::TStopwatch sw =
		System::Diagnostics::TStopwatch::Create();
	sw.Start();
	for (int I = 1; I <= Max; I++) {
		if (IsPrime(I)) {
			Tot++;
		}
	}
	sw.Stop();
	Memo1->Lines->Add
		(String().sprintf
		(L"Sequential For loop. Time (in milliseconds): %lld, Primes found: %lld",
		sw.ElapsedMilliseconds, Tot));
}

Кнопка «Параллельный цикл» запускает параллельную версию вычисления простых чисел:

// Button event handler that finds prime numbers using the Parallel::For method
void __fastcall TForm2::btnParallelLoopClick(TObject *Sender) {
	int Max = 5000000; // 5 Million
	Tot = 0;
	System::Diagnostics::TStopwatch sw =
		System::Diagnostics::TStopwatch::Create();
	sw.Start();

	// In C++, the IsPrime function passes to the TParallel.For as an Iterator Event.
	TParallel::For(NULL, 1, Max, MyIteratorEvent);

	// Second option is to use a C++11 Lambda for the Parallel::For

/*
    	TParallel::For(NULL, 1, Max, System::Sysutils::_di_TProc__1<int>(
    		// [this] (int AIndex) {
    		[&](int AIndex) {
    		if (IsPrime(AIndex)) {TInterlocked::Increment(Tot);};}));
*/

	sw.Stop();
	Memo1->Lines->Add
		(String().sprintf
		(L"Parallel For loop.      Time (in milliseconds): %lld, Primes found: %lld",
		sw.ElapsedMilliseconds, Tot));
}

В поле Memo отображается время вычисления между классическим циклом for for (int I = 1; I <= Max; I ++) и версией параллельного цикла for с использованием метода TParallel :: For:

memo-3

Как видно из расчетов, последовательному циклу For Loop потребовалось 814 миллисекунд, чтобы вычислить количество простых чисел от 1 до 5 миллионов, но для того же с использованием метода TParallel :: For требуется всего 267 миллисекунд. Я т ясно , что TParallel :: Для метода является более эффективным, и запускает приложение гораздо быстрее, так как он использует имеющийся процессор для выполнения процедур параллельно. Виртуальная машина, которую я использовал для своего раздела Windows, использует 4 ядра процессора, поэтому мы видим, что с помощью метода TParallel :: For приложение работает в основном в 4 раза быстрее! Чем больше ядер у вас будет, тем быстрее ваше приложение будет работать с использованием метода TParallel :: For!

Глядя на код, мы видим, как мы реализовали это приложение.
Если вы наведете курсор на #include <System.Threading.hpp> | Щелкните правой кнопкой мыши | Откройте файл в курсоре, вы откроете свой файл C: Program Files (x86) Embarcadero Studio 21.0 include windows rtl  System.Threading.hpp .

Затем с помощью методов Insight | ищите для

for-3

Мы видим, что у нас есть 43 метода использования TParallel.For .
Глядя на первый, мы видим в этом заголовке System.Threading.TParallel.For он включает ряд перегруженных аргументов, что делает его очень подходящим для разработки на C ++!

Библиотека параллельного программирования (PPL) включает эту функцию цикла TParallel :: For , которая позволяет запускать его циклы параллельно!

И для всего этого существует пул потоков, который автоматически настраивается автоматически (в зависимости от нагрузки на ЦП), поэтому вам не нужно заботиться о создании или управлении потоками для этой цели!

Чтобы использовать библиотеку параллельного программирования в своем приложении, просто включите заголовок System.Threading. Этот заголовок имеет несколько функций, которые можно включить в новые и существующие проекты C ++ Builder.

Возвращаясь к пользовательскому интерфейсу приложения, когда мы нажимаем кнопку For Loop, мы видим, что используем обычную последовательную функцию For Loop, и проверяем, является ли наше число от 1 до 5 миллионов простым числом.

Чтобы проверить, является ли число простым числом, мы используем эту функцию в нашем приложении

bool __fastcall TForm2::IsPrime(int N) {
	int Test, k;
	bool aPrime;
	if (N <= 3) {
		return N > 1;
	}
	else if (((N % 2) == 0) || ((N % 3) == 0)) {
		return false;
	}
	else {
		aPrime = true;
		k = (int)sqrt(N);
		Test = 5;
		while (Test <= k) {
			if (((N % Test) == 0) || ((N % (Test + 2)) == 0)) {
				aPrime = false;
				break; // jump out of the for loop
			}
			Test = Test + 6;
		}
		return aPrime;
	}
}

Затем, когда мы нажимаем кнопку Parallel Loop, мы видим, что используем метод RTL TParallel :: For. А в C ++ нашу функцию IsPrime необходимо передать методу TParallel.For либо как событие Iterator, либо как C ++ 11 Lambda.

Для события Iterator вот как мы реализовали функцию IsPrime как событие Iterator

// Parallel For Iterator Event Proc
void __fastcall TForm2::MyIteratorEvent(TObject* Sender, int AIndex) {
	// The Iterator Event implementation code is as follows.
	// In C++ you create an Iterator event function or C++11 lambda and
	// pass that as part of the TParallel::For loop call.
	//
	// Within parallel loops, you must transform your operations into thread-safe operations.
	// Here we use a member of the RTL System.SyncObjs header, the TInterlocked method.
	if (IsPrime(AIndex)) {
		TInterlocked::Increment(Tot);
	}
}

Второй вариант для передачи нашей функции C ++ IsPrime методу TParallel.For заключается в использовании лямбда- выражения C ++ 11 для Parallel :: For , как мы видим здесь в коде. Здесь мы видим наше лямбда-выражение: [&] (int AIndex) . Это захватывает нашу переменную по ссылке

// Second option is to use a C++11 Lambda for the Parallel::For
		TParallel::For(NULL, 1, Max, System::Sysutils::_di_TProc__1<int>(
			// [this] (int AIndex) {
			[&](int AIndex) {
			if (IsPrime(AIndex)) {TInterlocked::Increment(Tot);};}));

Если вы запустите то же приложение с использованием кода Lambda, вы получите те же результаты.

 

При запуске приложения мы увидели, что TParallel :: For более эффективен, поскольку он использует доступные процессоры для параллельного выполнения процедур. И это приложение также показывает поддержку C ++ 11 в C ++ Builder, включая поддержку лямбда-выражений!

В заключение, C ++ Builder RTL включает библиотеку параллельного программирования (PPL).

Одним из прекрасных способов использования PPL является ускорение цикла за счет использования метода TParallel.For.

PPL, часть C ++ Builder RTL, в заголовке System.Threading также дает вашим приложениям возможность выполнять задачи параллельно, используя преимущества работы на нескольких устройствах ЦП и компьютерах. PPL включает ряд расширенных функций для выполнения задач, объединения задач, ожидания групп задач, а также метод TParallel :: For, который мы только что видели в этом приложении.

Некоторые дополнительные полезные ссылки:

Использование RTL (библиотеки времени выполнения )

Учебное пособие: использование цикла For из библиотеки параллельного программирования

Видео: как использовать Parallel Prime для C ++ Builder VCL.

Загрузите бесплатную 30-дневную пробную версию C ++ Builder сегодня по этой ссылке

RAD Studio 13.2 Florence Now Available! Kai 1.1.1 Now Available! What's Coming in RAD Studio 13.2 Florence

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.

Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

IN THE ARTICLES