Wahrscheinlich sättigen Sie die Speicherbandbreite. Die Rechenintensität dieser Funktion ist sehr niedrig, und die Leistungen werden hauptsächlich durch die Zeiten von Speicherzugriffen bestimmt. Tatsächlich hängen die Skalierbarkeitsergebnisse stark von den Inkrementen incX und incY ab. Unter der Annahme, N = 10000000, fand ich, dass (CPU E5-2670):
N threads | time for incX=incY=1 | time for incX=incY=32
1 | 0.026271 | 1.243775
2 | 0.020599 | 0.555945
4 | 0.017871 | 0.301370
8 | 0.021367 | 0.152756
16 | 0.021729 | 0.175500
, das zeigt, dass die Geschwindigkeit-up anständig bis 8 Fäden (und noch immer dort bei 16 Fäden), wenn INCX/Y verschieden ist von 1. Wenn incX/Y = 1 ist, verwendet eine sehr gut optimierte Version der Funktion (mit signifikanter Verwendung von AVX-Funktionen) den größten Teil der verfügbaren Speicherbandbreite, was die Ergebnisse der OpenMP-Parallelisierung sehr schlecht macht. Ich rate nur, was passiert: Um das zu bestätigen, könnten Sie die Verwendung eines Low-Level-Profilers in Erwägung ziehen.
Die BLAS- und LAPACK-Bibliotheken, die mit Linux-Distributionen geliefert werden, sind single-threaded. Proprietäre Leistungsbibliotheks-Builds wie Intel MKL und AMD verfügen möglicherweise über integrierte OpenMP-Threads mit geeigneten Funktionen, jedoch nicht über alle Funktionen in der Bibliothek. Der Standardwert von mkl_set_num_threads ist die Anzahl der physischen Kerne. – tim18
MKL? Rot-Funktionen werden als Threads aufgelistet, aber es ist unwahrscheinlich, dass sie auf 24 Threads skaliert werden, auch wenn Sie 24 physische Cores und eine für die Skalierung optimale Problemgröße haben. ark.intel.com gibt an, dass Sie 6 Kerne pro CPU haben würden, so scheint es, dass die Einstellung von mehr als 12 Threads kontraproduktiv wäre. – tim18