программа застревает в операторе pthread_spin_unlock, когда оптимизация (O1 или O2 или O3) включена - PullRequest
0 голосов
/ 25 февраля 2012

Я пишу программу, которая имеет 8 потоков. Я реализую барьер, который имеет глобальный счетчик, который увеличивается каждым потоком, когда он обладает блокировкой. Все потоки ожидают в цикле while, чтобы это число стало 8, а когда оно станет 8, они должны продолжаться. Я вижу, что только поток, который сделал счет от 7 до 8, на самом деле завершает работу, в то время как все остальные потоки застревают в операторе разблокировки, который следует за приращением. Все это происходит только при включенной оптимизации O1, O2 или O3.

код

// some code

pthread_spin_lock (&lcl_mutex_1);
sync_count_1++; // global count 
pthread_spin_unlock (&lcl_mutex_1);

while (isbreak_1 == 0) {
    if (sync_count_1==8) {
         cout << a << endl; //a is argument that indicated the thread number.
         isbreak_1=1;
    }
}

// some code

Весь этот процесс работает нормально, когда оптимизация не включена.

Вот что я проверил. я скомпилировал с -O3 и -g на. поставить точку останова на

cout << a << endl;

линия. Я видел, что поток, который обновляет счет до 8, единственный, кто достиг этой точки останова. когда я использовал «информационные потоки», чтобы увидеть состояние других потоков, все они застряли в операторе pthread_spin_unlock.

Любая помощь для решения этой проблемы будет принята.

Добавление

//global declaration

pthread_spinlock_t lcl_mutex_1

//in main

pthread_spin_init (&lcl_mutex_1, 0);

Я скомпилировал код, используя g ++ -DUSE_SPINLOCK -O3 -g corr_coeff_parallel_v9.cpp -lpthread

Я также скопирую и вставлю вывод GDB

[Thread debugging using libthread_db enabled]
[New Thread 0x40a00940 (LWP 30485)]
[New Thread 0x41401940 (LWP 30486)]
[New Thread 0x41e02940 (LWP 30487)]
[New Thread 0x42803940 (LWP 30488)]
[New Thread 0x43204940 (LWP 30489)]
[New Thread 0x43c05940 (LWP 30490)]
[New Thread 0x44606940 (LWP 30491)]
[New Thread 0x45007940 (LWP 30492)]
Time is 53      0 //these are some time measurements I have made before the prolematic section
Time is 51      1
Time is 51      4
Time is 51      5
Time is 51      2
Time is 51      6
Time is 51      3
[Thread 0x2aaaaaabfc10 (LWP 30482) exited]
[Switching to Thread 0x44606940 (LWP 30491)]

Breakpoint 1, calc_corr (t=0x6) at corr_coeff_parallel_v9.cpp:337
337                                     cout << a << endl;
(gdb) info threads
9 Thread 0x45007940 (LWP 30492)  0x00000000004033e4 in calc_corr (t=0x7) at  corr_coeff_parallel_v9.cpp:334
* 8 Thread 0x44606940 (LWP 30491)  calc_corr (t=0x6) at corr_coeff_parallel_v9.cpp:337
7 Thread 0x43c05940 (LWP 30490)  0x00000000004033e4 in calc_corr (t=0x5) at corr_coeff_parallel_v9.cpp:334
6 Thread 0x43204940 (LWP 30489)  0x00000000004033e4 in calc_corr (t=0x4) at corr_coeff_parallel_v9.cpp:334
5 Thread 0x42803940 (LWP 30488)  0x00000000004033e4 in calc_corr (t=0x3) at corr_coeff_parallel_v9.cpp:334
4 Thread 0x41e02940 (LWP 30487)  0x00000000004033e4 in calc_corr (t=0x2) at corr_coeff_parallel_v9.cpp:334
3 Thread 0x41401940 (LWP 30486)  0x00000000004033e4 in calc_corr (t=0x1) at corr_coeff_parallel_v9.cpp:334
2 Thread 0x40a00940 (LWP 30485)  0x00000000004033e4 in calc_corr (t=0x0) at corr_coeff_parallel_v9.cpp:334
(gdb) 

1 Ответ

1 голос
/ 25 февраля 2012

Стандарт POSIX обеспечивает доступ к объекту в одном потоке, в то время как другой поток изменяет или может изменить его неопределенное поведение.Ваш код делает это, получая доступ к sync_count_1 в цикле while, в то время как другой поток может изменять его.Самое простое решение - удерживать спин-блокировку во время чтения.Другим решением было бы использование библиотеки (или встроенного, специфичного для компилятора, или ассемблерного кода), который обеспечивает элементарную операцию памяти с определенной семантикой видимости памяти между потоками.

...