2015-11-13 2 views
1

Насколько я знаю, эта программа должна получить ускорение в 2 или более раза при запуске с двумя потоками. Вместо этого я получаю почти то же самое, что и серийно.Не похоже, чтобы ускорить работу в openMP

static void proc_paralelo (int n, char *vprimos, int nthr) {

omp_set_num_threads(nthr); int i, j, prim, posiciones; int raiz_n = sqrt(n); for (i=1;i < raiz_n; i++) { if (vprimos[i]==0) { prim=i+1; posiciones=ceil((float)(n-(i+prim))/(float)prim); #pragma omp parallel for private(j) schedule (static, posiciones/omp_get_num_threads()) for (j=0; j<posiciones; j++){ vprimos[i+prim+(j*prim)]=1;} } } }

Количество потоков я использую 2 (сердечники моего процессора), и размером n является 20000000.

Времен я получаю:

  • серийно : 650000000 нс
  • параллельно: 630000000 нс
+1

Что должна делать ваша программа? Вы не должны получать ускорение более двух раз, используя 2 потока, кстати. –

+0

Сколько времени занимает 'posiciones', как правило? Если вы собираетесь использовать несколько потоков, он должен быть довольно большим. –

+0

Покажите нам, как вы измеряете время выполнения. – jepio

ответ

1

Запустив две темы, вы никогда не сможете (Редактировать: редко, см. Комментарии) см. Больше, чем 2x ускорение. На самом деле, поскольку никакая работа не является идеально параллелизуемой, вы, вероятно, даже не увидите этого. Считайте также, что запуск нового потока требует значительных ресурсов - вы, скорее всего, не увидите никаких выигрышей и можете увидеть потери производительности, если ваша рабочая нагрузка не будет достаточно тяжелой, чтобы насытить процессор дольше, чем время, затрачиваемое на создание нового потока (для Связанные с процессором рабочие нагрузки). Вы также будете ограничены конфликтом разделяемых ресурсов, поскольку ваши потоки разделяют некоторые аппаратные или программные ресурсы - см. Комментарии для некоторых примеров.

+0

Также могут возникать такие проблемы, как конкуренция за общий кэш ЦП, повышенный пейджинг и т. Д., Которые все сокращают скорость, которая может быть реализована при распараллеливании. –

+0

@JohnBollinger Отличная точка. – Patrick87

+2

Время от времени вы можете увидеть ускорение в 2x с использованием двух ядер. Очевидным примером может быть то, что вы используете данные, которые не будут входить в кеш одного ядра, но будут входить в два кэша ядра. В этом случае устранение большого объема доступа к основной памяти может повысить скорость, значительно превышающую 2x. Это не распространено, но я это видел. –

0

Мне кажется, проблема в том, что ваш код почти наверняка связан с памятью, а использование второго ядра не увеличивает вашу пропускную способность памяти.

В частности, ваш vprimos, по-видимому, составляет около 20 мегабайт, что слишком сильно подходит для кеша (по крайней мере, на большинстве процессоров). Фактический расчет, который вы делаете для одной итерации, абсолютно тривиален (вычисляет адрес и записывает 1), поэтому даже для одного ядра вы, вероятно, в основном связаны с памятью. Добавление второго ядра экономит маленький бит (возможно, для частей, которые - в кеше), но это все.

В этом случае одним очевидным преимуществом будет использование одного бита для хранения каждого булева вместо использования всего символа. Хотя он добавляет некоторые вычислительные накладные расходы, он, вероятно, сохранит достаточную пропускную способность памяти, чтобы компенсировать больше.

Один пример, который я выбрал вместе назад (также из Sieve of Eratosthenes), кажется, работает примерно в шесть раз быстрее, чем ваш, для одного и того же размера (хотя это C++ вместо C).

Смежные вопросы