#include <iostream>
#include <cmath>
#include <numeric>
#include <vector>
#include <algorithm>
#include <thread>
#include <stdio.h>
// Determines if a point of dimension point.size() is within the sphere
bool isPointWithinSphere(std::vector<int> point, const double &radius) {
// Since we know that the sphere is centered at the origin, we can simply
// find the euclidean distance (square root of the sum of squares) and check to
// see if it is less than or equal to the length of the radius
//square each element inside the point vector
std::transform(point.begin(), point.end(), point.begin(), [](auto &x){return std::pow(x,2);});
//find the square root of the sum of squares and check if it is less than or equal to the radius
return std::sqrt(std::accumulate(point.begin(), point.end(), 0, std::plus<int>())) <= radius;
}
// Counts the number of lattice points inside the sphere(all points (x1 .... xn) such that xi is an integer)
// The algorithm: If the radius is a floating point value, first find the floor of the radius and cast it to
// an integer. For example, if the radius is 2.43 then the only integer points we must check are those between
// -2 and 2. We generate these points by simulating n - nested loops using recursion and passing each point
// in to the boolean function isPointWithinSphere(...), if the function returns true, we add one to the count
// (we have found a lattice point on the sphere).
int countLatticePoints(std::vector<int> &point, const double radius, const int dimension, int count = 0) {
const int R = static_cast<int>(std::floor(radius));
for(int i = -R; i <= R; i++) {
point.push_back(i);
if(point.size() == dimension){
if(isPointWithinSphere(point, radius)) count++;
}else count = countLatticePoints(point, radius, dimension, count);
point.pop_back();
}
return count;
}
int main(int argc, char ** argv) {
std::vector<int> vec {};
std::vector<std::thread> threads;
auto max_threads = std::thread::hardware_concurrency();
for(unsigned i = 0; i < max_threads; ++i)
threads.push_back(std::thread(countLatticePoints, vec, atof(argv[1]), atoi(argv[2])));
std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
return 0;
}
Ich versuche, die obige Berechnung parallel auszuführen. Grundsätzlich möchte ich die Funktion countLatticePoints(vec, 1.05, 3)
aufrufen, so dass die maximale Anzahl von Threads auf meinem System die Berechnung ausführt und ein Endergebnis zurückgibt. Ich habe Schwierigkeiten, dies aufzustellen. Was ich versucht habe, ist, dass alle Threads zu meiner Berechnung gehören, aber ich bekomme die folgende, sehr nicht entzifferbare Fehlermeldung.C++ STL Multithreading, laufende Berechnung parallel
g++ nDimensionalSphere.cpp -o nDimensionalSphere -std=c++14 -pthread
In file included from /usr/include/c++/4.9/thread:39:0,
from nDimensionalSphere.cpp:6:
/usr/include/c++/4.9/functional: In instantiation of ‘struct std::_Bind_simple<int (*(std::vector<int>, double, int))(std::vector<int>&, double, int, int)>’:
/usr/include/c++/4.9/thread:140:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = int (&)(std::vector<int>&, double, int, int); _Args = {std::vector<int, std::allocator<int> >&, double, int}]’
nDimensionalSphere.cpp:56:92: required from here
/usr/include/c++/4.9/functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<int (*(std::vector<int>, double, int))(std::vector<int>&, double, int, int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.9/functional:1695:9: error: no type named ‘type’ in ‘class std::result_of<int (*(std::vector<int>, double, int))(std::vector<int>&, double, int, int)>’
_M_invoke(_Index_tuple<_Indices...>)
^
Zusätzlich zu dem Kompilierungsfehler haben Sie ein viel größeres Problem. Es scheint, dass jeder Thread versucht, "push_back"() zu demselben "std :: vector" zu senden. Da 'std :: vector' keine Threadsicherheit garantiert, führt dies zu undefiniertem Verhalten. –
@SamVarshavchik Oh aber das 'pop_back' am Ende der Schleife macht noch mehr Spaß :) – kfsone
Ja, das ganze Ding ist gerade jenseits des Punktes der Rettung. –