Прежде всего, простой точечный продукт из 1000 элементов не обладает достаточными вычислительными затратами для оправдания многопоточности - вы заплатите гораздо больше затрат на связь и синхронизацию, чем вы получите в производительности, что оно не стоит это.
Во-вторых, похоже, что вы вычисляете произведение полной точки в каждом потоке, не разделяя вычисления на несколько потоков и объединяя результат в конце.
Вот пример того, как сделать продукты векторной точки из https://computing.llnl.gov/tutorials/openMP/#SHARED
#include <omp.h>
main ()
{
int i, n, chunk;
float a[100], b[100], result;
/* Some initializations */
n = 100;
chunk = 10;
result = 0.0;
for (i=0; i < n; i++) {
a[i] = i * 1.0;
b[i] = i * 2.0;
}
#pragma omp parallel for \
default(shared) private(i) \
schedule(static,chunk) \
reduction(+:result)
for (i=0; i < n; i++)
result += (a[i] * b[i]);
printf("Final result= %f\n",result);
}
По сути, OpenMP хорош для выполнения грубого параллелизма, когда у вас большие, дорогие циклы. В общем, когда вы выполняете параллельное программирование, чем больше «кусков» вычислений вы можете сделать перед повторной синхронизацией, тем лучше. Тем более, что количество ядер увеличивается, расходы на связь и синхронизацию будут расти. Представьте, что каждая синхронизация (получение нового индекса или части индексов для выполнения, вход в критический раздел и т. Д.) Обходится вам в 10 мс или 1 МБ инструкций, чтобы получить лучшее представление о том, когда / где / как распараллеливать ваш код.