Lösungsvorschlag

Zur ersten Frage: Die vorgeschlagene Fassung ist nicht thread safe, da alle Threads unkontrolliert auf eine gemeinsame Datenstruktur zugreifen: den Pseudo-Zufallszahlengenerator. Das Verhalten ist dann nicht mehr wohldefiniert, da sich dann mehrere Threads gleichzeitig den Generator aufrufen können, wobei dann einige Threads möglicherweise einen inkonsistenten Zustand vorfinden. Die Auswirkungen eines solchen Fehlers sind nicht unmittelbar ersichtlich. Es wäre denkbar, dass nur die zugesicherten Eigenschaften des Generators nicht mehr erfüllt sind. Bei ungünstigen Umständen könnte es vielleicht auch selten zu einem Crash führen.

Hier ist ein Lösungsvorschlag zur zweiten Aufgabe, der auf die Matrix A zwei Sichten erzeugt für die obere und untere Hälfte und diese dann mit Hilfe zweiter Threads getrennt initialisiert.

#include <thread>
#include <random>
#include <hpc/matvec/gematrix.h>
#include <hpc/matvec/apply.h>
#include <hpc/matvec/print.h>

template<typename MA>
typename std::enable_if<hpc::matvec::IsRealGeMatrix<MA>::value, void>::type
randomInit(MA& A) {
   using ElementType = typename MA::ElementType;
   using Index = typename MA::Index;

   std::random_device random;
   std::mt19937 mt(random());
   std::uniform_real_distribution<ElementType> uniform(-100,100);

   hpc::matvec::apply(A, [&](ElementType& val, Index i, Index j) -> void {
      val = uniform(mt);
   });
}

int main() {
   using namespace hpc::matvec;
   GeMatrix<double> A(1000, 1000);

   auto half = A.numRows / 2;
   auto A1 = A(0, 0, half, A.numCols);
   auto A2 = A(half, 0, A.numRows - half, A.numCols);

   std::thread t1([&](){ randomInit(A1); });
   std::thread t2([&](){ randomInit(A2); });
   t1.join(); t2.join();

   /* print a small block of each of the initialized matrices */
   auto A_ = A(half-2, half-2, 5, 5);
   print(A_, "A_");
}