OpenMP 3.0以降が提供するロック操作関数では、ロック所有権はスレッドではなく “タスクにより所有” される。一方で、ベース言語が提供するロック操作*1ではロック所有権が “スレッドにより所有” されるため、OpenMPロック操作関数の代替とできないユースケースが存在する。
OpenMP 2.5以前
OpenMP 2.5以前はロックがスレッドにより所有される設計となっている。すなわち、ロック獲得/解放操作を同一スレッド上から行う必要がある。
OpenMP API Version 2.5仕様*2, 3.3 Lock Routinesより一部引用(下線部は強調)。
3.3 Lock Routines
An OpenMP lock may be in one of the following states: uninitialized, unlocked, or locked. If a lock is in the unlocked state, a thread may set the lock, which changes its state to locked. The thread which sets the lock is then said to own the lock. A thread which owns a lock may unset that lock, returning it to the unlocked state. A thread may not set or unset a lock which is owned by another thread.
OpenMP 3.0以降
OpenMP 3.0での “タスク(task)” 導入に伴って、ロックがタスクにより所有される設計となっている。すなわち、ロック獲得/解放操作を同一タスク上から行う必要がある。明示的にuntied taskを用いる場合、タスクを実行するスレッドが途中で切り替わる可能性があるため、OpenMP提供ロック操作関数でないと正しくロック解放を行えない。(既定ではtied taskとなるため、タスクを実行するスレッドは固定化される。)
OpenMP API Version 3.0仕様*3, 3.3 Lock Routines, A.43 Ownership of Locks, APPENDIX Fより一部引用(下線部は強調)。
3.3 Lock Routines
An OpenMP lock may be in one of the following states: uninitialized, unlocked, or locked. If a lock is in the unlocked state, a task may set the lock, which changes its state to locked. The task which sets the lock is then said to own the lock. A task which owns a lock may unset that lock, returning it to the unlocked state. A program in which a task unsets a lock that is owned by another task is non-conforming.
A.43 Ownership of Locks
Ownership of locks has changed from OpenMP 2.5 to OpenMP 3.0. In OpenMP 2.5, locks are owned by threads; so a lock released by theomp_unset_lock
routine must be owned by the same thread executing the routine. In OpenMP 3.0, on the other hand, locks are owned by task regions; so a lock released by theomp_unset_lock
routine in a task region must be owned by the same task region.
Changes from Version 2.5 to Version 3.0
- In Version 3.0, locks are owned by tasks, not by threads (see Section 3.3 on page 134).
関連URL
*1:pthread_mutex_lock(POSIX), EnterCriticalSection(WindowsAPI), std::mutex(C++標準ライブラリ)など。