Ich frage mich, ob es eine leichte, direkte Möglichkeit gibt, Schleifen in C++ zu berechnen, z. Wie würdest du so etwas umsetzen? Von Scala kenne ich die Karten-, Filter- und Foreach-Funktionen vielleicht könnte man diese auch parallel durchführen? Gibt es einen einfachen Weg, dies in C++ zu erreichen? Meine primäre Plattform ist Linux, aber es wäre schön, wenn es plattformübergreifend funktioniert.Parallele Schleifen in C++
Antwort
Was ist Ihre Plattform? Sie können OpenMP betrachten, obwohl es kein Teil von C++ ist. Aber es wird von Compilern weitgehend unterstützt.
Wie für bereichsbasierte for-Schleifen, siehe z. B. Using OpenMP with C++11 range-based for loops?.
Ich habe auch einige Dokumente bei http://www.open-std.org gesehen, die einige Bemühungen zeigen, parallele Konstrukte/Algorithmen in zukünftiges C++ einzubauen, aber nicht wissen, was ihr aktueller Status ist.
UPDATE
nur einige beispielhafte Code hinzufügen:
template <typename RAIter>
void loop_in_parallel(RAIter first, RAIter last) {
const size_t n = std::distance(first, last);
#pragma omp parallel for
for (size_t i = 0; i < n; i++) {
auto& elem = *(first + i);
// do whatever you want with elem
}
}
Die Anzahl der Fäden zur Laufzeit über das OMP_NUM_THREADS
Umgebungsvariable gesetzt werden kann.
Lets sagen, ich habe eine nicht so teure Operation in der Schleife ist es möglich, die Schleife in zwei Hälften zu teilen? Auf dem Faden macht die eine Hälfte den Rest? Gleiches mit 3 und so weiter Themen? – Exagon
Was wiederholst du? Können Sie Indizes zum Schleifen verwenden? –
@Exagon Es hängt von Ihnen ab, auf welche Weise Sie Arbeit von Threads nehmen. Sie können Bedingungen in Schleifen festlegen, mit denen Sie die Arbeit teilen können. –
Dies kann mit threads
speziell pthreads
Bibliotheksfunktion durchgeführt werden, die verwendet werden kann, um Operationen gleichzeitig durchzuführen.
Sie können mehr über sie hier lesen: http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm
std :: Thread kann auch verwendet werden: http://www.cplusplus.com/reference/thread/thread/
Unten ist ein Code, in dem ich die Thread-ID jedes Threads verwenden das Array aufgeteilt in zwei Hälften:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 2
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
void *splitLoop(void *threadid)
{
long tid;
tid = (long)threadid;
//cout << "Hello World! Thread ID, " << tid << endl;
int start = (tid * 5);
int end = start + 5;
for(int i = start;i < end;i++){
cout << arr[i] << " ";
}
cout << endl;
pthread_exit(NULL);
}
int main()
{
pthread_t threads[NUM_THREADS];
int rc;
int i;
for(i=0; i < NUM_THREADS; i++){
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL,
splitLoop, (void *)i);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
Denken Sie auch daran beim Kompilieren Sie die -lpthread
Flagge verwenden.
Link zur Lösung auf Ideone: http://ideone.com/KcsW4P
Ja, das erreicht werden kann, können Sie den 'Start-Index' und den 'End-Index' in der Funktion, die Sie verwenden, angeben und für jeden zu verwendenden Thread entsprechend ändern. – uSeemSurprised
Die Funktion 'pthread_create' nimmt ein Argument an, das den Namen der Funktion enthält, die die Threads verwenden sollen. Sie können diese Funktionsargumente ändern, um das gewünschte Ergebnis zu erzielen. – uSeemSurprised
warum würde er pthreads verwenden wollen, wenn er 'std :: thread' hat? –
std::async
kann hier eine gute Passform sein, wenn Sie gerne die C++
Laufzeit die Parallelität steuern lassen.
Beispiel aus der cppreference.com:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
template <typename RAIter>
int parallel_sum(RAIter beg, RAIter end)
{
auto len = end - beg;
if(len < 1000)
return std::accumulate(beg, end, 0);
RAIter mid = beg + len/2;
auto handle = std::async(std::launch::async,
parallel_sum<RAIter>, mid, end);
int sum = parallel_sum(beg, mid);
return sum + handle.get();
}
int main()
{
std::vector<int> v(10000, 1);
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
}
wow danke ich denke, ich werde das verwenden – Exagon
gibt es irgendwelche Dokumentation darüber, wie C++ die parallelen Aufgaben und asyncs behandelt? – Exagon
Der erste Parameter für 'std :: async()' gibt an, welche Freiheit Sie dem Framework geben (in erster Linie, ob Sie die Verwendung des Vordergrund-Threads zulassen). Was es für den Hintergrund tut - es ist Compiler-spezifisch, aber höchstwahrscheinlich wird es bei den meisten Compilern einen Singleton-Thread-Pool mit N = Anzahl von CPU-Kernen auf der Box geben. Die beste Gebrauchsdokumentation, die ich bisher gefunden habe, ist das Nebenläufigkeitskapitel aus dem letzten Mayer-Buch. – bobah
mit den Parallelalgorithmen in C++ 17 wir verwenden:
std::vector<std::string> foo;
std::for_each(
std::execution::par_unseq,
foo.begin(),
foo.end(),
[](auto&& item)
{
//do stuff with item
});
zu berechnen Schleifen parallel. Der erste Parameter gibt die execution policy
Mit C++ 11 können Sie eine for-Schleife mit nur ein paar Zeilen von Codes parallelisieren.Diese spaltet eine for-Schleife in kleinere Stücke und weisen jede Unterschleife zu einem Thread:
/// Basically replacing:
void sequential_for(){
for(int i = 0; i < nb_elements; ++i)
computation(i);
}
/// By:
void threaded_for(){
parallel_for(nb_elements, [&](int start, int end){
for(int i = start; i < end; ++i)
computation(i);
});
}
Oder withing eine Klasse:
struct My_obj {
/// Replacing:
void sequential_for(){
for(int i = 0; i < nb_elements; ++i)
computation(i);
}
/// By:
void threaded_for(){
parallel_for(nb_elements, [this](int s, int e){ this->process_chunk(s, e); });
}
void process_chunk(int start, int end)
{
for(int i = start; i < end; ++i)
computation(i);
}
};
Um dies zu tun, müssen Sie nur den Code setzen unten eine Header-Datei und verwenden Sie es nach Belieben:
#include <algorithm>
#include <thread>
#include <functional>
#include <vector>
/// @param[in] nb_elements : size of your for loop
/// @param[in] functor(start, end) :
/// your function processing a sub chunk of the for loop.
/// "start" is the first index to process (included) until the index "end"
/// (excluded)
/// @code
/// for(int i = start; i < end; ++i)
/// computation(i);
/// @endcode
/// @param use_threads : enable/disable threads.
///
///
static
void parallel_for(unsigned nb_elements,
std::function<void (int start, int end)> functor,
bool use_threads = true)
{
// -------
unsigned nb_threads_hint = std::thread::hardware_concurrency();
unsigned nb_threads = nb_threads_hint == 0 ? 8 : (nb_threads_hint);
unsigned batch_size = nb_elements/nb_threads;
unsigned batch_remainder = nb_elements % nb_threads;
std::vector<std::thread> my_threads(nb_threads);
if(use_threads)
{
// Multithread execution
for(unsigned i = 0; i < nb_threads; ++i)
{
int start = i * batch_size;
my_threads[i] = std::thread(functor, start, start+batch_size);
}
}
else
{
// Single thread execution (for easy debugging)
for(unsigned i = 0; i < nb_threads; ++i){
int start = i * batch_size;
functor(start, start+batch_size);
}
}
// Deform the elements left
int start = nb_threads * batch_size;
functor(start, start+batch_remainder);
// Wait for the other thread to finish their task
if(use_threads)
std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
}
- 1. parallele foreach Schleifen erzeugen mclapply Fehler
- 2. Parallele Pipeline in C#
- 3. Parallele Zuweisung in C++
- 4. Parallele Programmierung in C#
- 5. Parallele maximale Laufzeit für MatLab Funktion in Schleifen
- 6. Parallele Array-Verarbeitung C++
- 7. Parallele Programmierung von C++?
- 8. Multiprocessing unterstützte parallele Schleifen können nicht unter Threads verschachtelt werden
- 9. Parallele For-Schleife in C# mit geteilter Variable
- 10. bereichsbasierte for-Schleifen in C++
- 11. Pointers und Schleifen in C
- 12. Schleifen in Schleifen in Schleifen in Java
- 13. C++ 11 Threading vs OpenMP für einfache parallele Schleifen. Welches wann?
- 14. Nested foreach Schleifen C#
- 15. Verschachtelung während Schleifen (C#)
- 16. Parallele API für C/C++ unter Windows
- 17. Parallele Verarbeitung in C# mit EF-Aufruf
- 18. Parallele Prozesse mit Semaphoren in C
- 19. So verschachteln Sie parallele Schleifen in einer sequenziellen Schleife mit OpenMP
- 20. parallele Verarbeitung in Fledermaus-Datei für Schleife
- 21. C# - Lambda vs verschachtelte Schleifen
- 22. C# verschachtelte Schleifen + Catch-Problem?
- 23. 3 C++ Schleifen in Cuda entpacken
- 24. Zuordnung Speicher, wenn foreach-Schleifen in C#
- 25. während Schleifen in c Sprache Iteration
- 26. Parallele Iteratoren
- 27. Parallele/redundante Replikation in CouchDB
- 28. Parallele Array-Zuweisung in PHP
- 29. C# zu VB.NET Framework 4 parallele Programmierung
- 30. C# Aufgabe parallele Bibliothek und NHibernate/Spring.NET
mit Threads ist eine gute Option. –
Ist es nicht wirklich teuer, Threads zu initialisieren? – Exagon
Im Vergleich zum Aufruf von fork(). Threads sind nicht teuer, da sie die Ressourcen aus dem Hauptthread teilen, außer sie haben ihren eigenen PC, Register und Stack. –