Параллельное программирование в Dual-Core обрабатывается одним ядром - PullRequest
1 голос
/ 15 ноября 2011

У меня двухъядерный процессор AMD Athlon II P320 с частотой 2,10 ГГц.

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

#include <stdio.h>
#include <omp.h>

int main (void){
    int i;

    #pragma omp parallel for
    for ( i = 1; i < 100; i++){
        printf("%d ", i);
        fflush(stdout);
    }
}

Я ожидаю, что выходные данные будут первыми 99 числами в случайном порядке, но мой вывод - первые 99 чисел в порядке возрастания. В чем здесь проблема?

Ответы [ 4 ]

2 голосов
/ 15 ноября 2011

Я тестировал на двухъядерном процессоре (или установил omp_set_num_threads(2) на четырех или более ядрах) и Windows , и я могу видеть ваш результат.Для ответа ChirsBD, компиляторы не могут игнорировать такие printf.Код OP будет распараллелен и будет выполняться параллельно.

  1. Вы используете статическое планирование OpenMP по умолчанию и используете 2 ядра.Итак, первое ядро ​​будет распечатано от 1 до 50, а другое - от 51 до 100. Но наблюдение состоит в том, что вы не можете видеть некоторые расы.

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

  3. Однако вычисление, которое является простым printf, слишком короткое.Таким образом, в то время как второй поток заблокирован для первой попытки получить критическую секцию, первый поток просто печатает все числа.Это означает, что {время получения и освобождения критической секции 50 раз} <{время минимальной блокировки второго потока}. </p>

  4. Если вы подставили фиктивное вычисление, такое какfor (volatile int k = 0; k < 100; ++k);, вы увидите чередование, но блокировка все еще активирована: вывод будет в основном "1 51 2 52 ...".

  5. Однако, когда я запускаю этот код в Linux, я вижукакой-то случайный порядок .Это связано с тем, что реализация и внутренняя блокировка stdout в Linux могут отличаться от Windows.

Подводя итог, можно сказать, что такая сериализация вызвана реализацией printf и слишком коротким параллельным вычислениемпетля.Таким образом, это не проблема.

1 голос
/ 15 ноября 2011

Парелизация такого цикла недействительна из-за printf, который вы выполняете в том же выходном потоке. Вывод в такой поток является мьютексом, поэтому даже если openMP удастся запустить отдельные потоки, они будут вынуждены последовательно обращаться к этому ресурсу.

Пишите потоки в разных файлах, каждый, и вы можете увидеть разницу. Но для того, чтобы действительно его увидеть, во внутренней части должно быть что-то, что связано с вычислениями, а не с IO.

0 голосов
/ 19 ноября 2011

Причина, по которой вы получаете этот вывод, заключается в том, что по умолчанию openMP использует статическое разбиение. Таким образом, для двух ядер он разделит интервал 0..100 на 0..50 и 51..100. Теперь, поскольку интервал действительно мал, печать 50 чисел одним потоком (скорее всего) произойдет до того, как другому потоку даже удастся запустить. Вот почему вы видите непрерывные числа, а не чередование.

0 голосов
/ 15 ноября 2011

Я подозреваю, что, поскольку это настолько простой процесс, что оптимизация компилятора имеет приоритет.

Попробуйте написать его как рекурсивный вызов функции для себя вместо цикла и посмотрите, что произойдет.

...