![Barcode For FMX | Embarcadero RAD Studio Delphi C++Builder Blogs](https://i0.wp.com/blogs.embarcadero.com/wp-content/uploads/2020/08/Barcode-For-FMX-1.jpg?resize=1024%2C694&ssl=1)
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 | Embarcadero RAD Studio Delphi C++Builder Blogs ui 4](https://i0.wp.com/blogs.embarcadero.com/wp-content/uploads/2020/08/UI.jpg?resize=642%2C234&ssl=1)
Вот приложение проекта C ++ Builder, которое использует общую библиотеку времени выполнения в приложении для нескольких устройств, используя заголовок RTL System.Threading и библиотеку параллельного программирования.
1 2 3 |
#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.
В пользовательском интерфейсе приложений:
Кнопка «Для цикла» запустит серийную версию расчета простых чисе
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 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)); } |
Кнопка «Параллельный цикл» запускает параллельную версию вычисления простых чисел:
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 |
// 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 | Embarcadero RAD Studio Delphi C++Builder Blogs memo 3](https://i0.wp.com/blogs.embarcadero.com/wp-content/uploads/2020/08/Memo.jpg?resize=474%2C53&ssl=1)
Как видно из расчетов, последовательному циклу 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 | Embarcadero RAD Studio Delphi C++Builder Blogs for 3](https://i0.wp.com/blogs.embarcadero.com/wp-content/uploads/2020/08/For.jpg?resize=556%2C262&ssl=1)
Мы видим, что у нас есть 43 метода использования TParallel.For .
Глядя на первый, мы видим в этом заголовке System.Threading.TParallel.For он включает ряд перегруженных аргументов, что делает его очень подходящим для разработки на C ++!
Библиотека параллельного программирования (PPL) включает эту функцию цикла TParallel :: For , которая позволяет запускать его циклы параллельно!
И для всего этого существует пул потоков, который автоматически настраивается автоматически (в зависимости от нагрузки на ЦП), поэтому вам не нужно заботиться о создании или управлении потоками для этой цели!
Чтобы использовать библиотеку параллельного программирования в своем приложении, просто включите заголовок System.Threading. Этот заголовок имеет несколько функций, которые можно включить в новые и существующие проекты C ++ Builder.
Возвращаясь к пользовательскому интерфейсу приложения, когда мы нажимаем кнопку For Loop, мы видим, что используем обычную последовательную функцию For Loop, и проверяем, является ли наше число от 1 до 5 миллионов простым числом.
Чтобы проверить, является ли число простым числом, мы используем эту функцию в нашем приложении
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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
1 2 3 4 5 6 7 8 9 10 11 12 |
// 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) . Это захватывает нашу переменную по ссылке
1 2 3 4 5 |
// 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 сегодня по этой ссылке
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition