![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 fornece três níveis de desenvolvimento:
1. Componentes (VCL e FMX)
2. Bibliotecas Comuns (RTL).
3. APIs de plataforma (iOS, Android, Mac OS)
Nesta postagem, discutiremos as Bibliotecas Comuns (RTL).
C ++ Builder tem várias centenas de funções, macros e classes que você chama de seus programas C e C ++ para realizar uma ampla variedade de tarefas, incluindo E / S de baixo e alto nível, string e manipulação de arquivo, alocação de memória, controle de processo , conversão de dados, cálculos matemáticos e muito mais.
A Biblioteca de Tempo de Execução do C ++ Builder (ou RTL) é composta por vários arquivos de cabeçalho básicos que fornecem o suporte básico para a maioria das bibliotecas de componentes VCL e FireMonkey. A RTL inclui rotinas globais, aulas de utilidade pública, como aqueles que representam fluxos e listas, e classes, como TObject, TPersistent e TComponent.
Embora intimamente com FireMonkey e VCL, a RTL não inclui qualquer um dos componentes que aparecem na Paleta de ferramentas.
Em vez disso, as classes e rotinas na RTL são usadas pelos componentes que aparecem na paleta de ferramentas, e estão disponíveis para você usar no código do aplicativo em qualquer projetos VCL ou projetos FireMonkey, ou quando você está escrevendo suas próprias classes.
por exemplo, o cabeçalho do sistema contém a maior parte da Biblioteca Run-Time (RTL).
E a partir do cabeçalho do sistema, você tem a System.Math.hpp cabeçalho que define as classes, rotinas, tipos, variáveis e constantes relacionadas com operações matemáticas, vetores e matrizes.
Ou o System.Bluetooth.hpp cabeçalho que fornece classes de uso as capacidades Bluetooth do dispositivo que está executando o aplicativo para conectar a aplicativos executados em dispositivos remotos.
Ou o System.Sensors.hpp cabeçalho que fornece classes e componentes que permitem obter informações e gerenciar sensores do sistema. Os sensores são peças de hardware ou software que podem fornecer medidas de grandezas físicas para suas aplicações.
Ou o System.Threading.hppcabeçalho que define as classes e tipos que implementam a biblioteca de programação paralela.
agora olhar para um exemplo C ++ Builder usando Let System.Threading.hpp cabeçalho eo Programação Paralela Library.
Para o meu exemplo de aplicação, eu vou estar usando um construtor de C ++ 10,4 aplicativo de projeto que usa uma Common Run Time Library, em um Multi-Device Application, usando o cabeçalho System.Threading da RTL e a Parallel Programming Library.
Você pode baixar este aplicativo de projeto TParallelPrime.cbproj de amostra aqui.
![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)
Aqui está um aplicativo de projeto C ++ Builder que usa uma Biblioteca de tempo de execução comum, em um aplicativo de vários dispositivos, usando o cabeçalho System.Threading da RTL e a biblioteca de programação paralela.
1 2 3 |
#include <System.Threading.hpp> // TParallel::For #include <System.Diagnostics.hpp> // System::Diagnostics::TStopwatch #include <System.SyncObjs.hpp> // TInterlocked::Increment |
Este exemplo mostra como usar o método TParallel.For da Parallel Programming Library (PPL) . TParallel.For divide um loop for em partes que são executadas em paralelo e usa tarefas para executar essas partes.
Este aplicativo encontra o número de números primos, entre 1 e um valor MAX, como 5 milhões neste aplicativo. O aplicativo calculará o tempo para fazer isso usando (1) o loop for clássico e faremos o mesmo usando a versão paralela usando o método TParallel.For.
Na IU dos aplicativos:
O botão “For Loop” iniciará a versão serial do cálculo dos números primos
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)); } |
O botão “Loop paralelo” irá lançar a versão paralela do cálculo de números primos:
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)); } |
A caixa Memorando exibe os tempos de cálculo entre o loop for clássico para (int I = 1; I <= Max; I ++) e a versão do loop for paralelo usando o método 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)
Como podemos ver a partir dos cálculos, o For Loop serial levou 814 milissegundos para calcular o número de números primos entre 1 e 5 milhões, mas levou apenas 267 milissegundos para fazer o mesmo usando o método TParallel :: For. I t é claro que o TParallel :: Para método é mais eficiente, e executa o aplicativo muito mais rápido, uma vez que faz uso da CPU está disponível para a execução de procedimentos em paralelo. A Máquina Virtual que usei para minha partição Windows está usando 4 núcleos de processador, então vemos que usando o método TParallel :: For, o aplicativo roda basicamente 4 vezes mais rápido! Quanto mais núcleos você tiver, mais rápido seu aplicativo será executado usando o método TParallel :: For!
Olhando para o código, vemos como implementamos este aplicativo.
Se você passar o cursor sobre o #include <System.Threading.hpp> | Clique com o botão direito | Abra o arquivo no Cursor, você abrirá o arquivo C: Arquivos de programas (x86) Embarcadero Studio 21.0 include windows rtl System.Threading.hpp .
Em seguida, usando Methods Insight | procure por For
![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)
Vemos que temos 43 métodos para usar TParallel.For .
Olhando para o primeiro, vemos neste cabeçalho System.Threading.TParallel.For, ele inclui uma série de argumentos sobrecarregados para torná-lo muito adequado para desenvolvimento em C ++!
A biblioteca de programação paralela (PPL) inclui esta função de loop, TParallel :: For , que permite executar seus loops em paralelo!
E para tudo isso, existe um Thread Pool que se auto-ajusta automaticamente (com base na carga da CPU) para que você não precise se preocupar em criar ou gerenciar threads para esse propósito!
Para usar a Biblioteca de Programação Paralela em seu aplicativo, basta incluir o cabeçalho System.Threading. Este cabeçalho possui vários recursos que podem ser incluídos em projetos C ++ Builder novos e existentes.
Voltando à IU dos aplicativos, quando clicamos no botão For Loop, vemos que estamos usando a função For Loop serial regular e verificamos se nosso número de 1 a 5 milhões é um número Prime.
Para verificar se o número é um número primo, usamos esta função em nosso aplicativo
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; } } |
A seguir, quando clicamos no botão Parallel Loop, vemos que estamos usando o método TParallel :: For da RTL. E em C ++ nossa função IsPrime precisa ser passada para o método TParallel.For como um evento Iterator ou como um Lambda C ++ 11.
Para o evento Iterator , aqui está como implementamos a função IsPrime como um evento 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); } } |
A segunda opção, para que nossa função C ++ IsPrime seja passada para o método TParallel.For , é usar um Lambda C ++ 11 para Parallel :: For , como vemos aqui no código. Aqui vemos nossa Expressão Lambda: [&] (int AIndex) . Isso captura nossa variável por ref
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);};})); |
Se você executar o mesmo aplicativo usando o código Lambda, obterá os mesmos resultados.
Executando a aplicação, vimos como o TParallel :: For é mais eficiente, pois faz uso das CPUs disponíveis para a execução de procedimentos em paralelo. E este aplicativo também mostra suporte a C ++ 11 no C ++ Builder, incluindo suporte para expressões Lambda!
Em conclusão, o C ++ Builder RTL inclui uma Biblioteca de Programação Paralela (PPL).
Um ótimo uso do PPL é tornar o looping mais rápido, usando o método TParallel.For.
O PPL, parte do C ++ Builder RTL, no cabeçalho System.Threading também oferece a seus aplicativos a capacidade de executar tarefas em paralelo, aproveitando o trabalho em vários dispositivos de CPU e computadores. O PPL inclui uma série de recursos avançados para executar tarefas, unir tarefas, aguardar grupos de tarefas, bem como o método TParallel :: For que acabamos de ver nesta aplicação.
Algumas referências adicionais úteis:
Usando a RTL (Biblioteca em tempo de execução )
Tutorial: Usando o For Loop da Biblioteca de Programação Paralela
Vídeo: Como usar o Parallel Prime para C ++ Builder VCL.
Baixe sua avaliação gratuita de 30 dias do C ++ Builder hoje a partir deste link
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition