OpenMP Yönergeleri
OpenMP API'sinde kullanılan yönergelerin bağlantılarını sağlar.
Visual C++ aşağıdaki OpenMP yönergelerini destekler.
Paralel iş paylaşımı için:
Yönerge | Tanım |
---|---|
parallel | Birden çok iş parçacığı tarafından paralel olarak yürütülecek olan bir paralel bölge tanımlar. |
for | Paralel bölge içindeki bir for döngüde yapılan işin iş parçacıkları arasında bölünmesine neden olur. |
Bölüm | Tüm iş parçacıkları arasında bölünecek kod bölümlerini tanımlar. |
single | Kodun bir bölümünün ana iş parçacığında değil, tek bir iş parçacığında yürütülmesi gerektiğini belirtmenize olanak tanır. |
Ana iş parçacığı ve eşitleme için:
Yönerge | Tanım |
---|---|
master | Yalnızca ana iş parçacığının programın bir bölümünü yürütmesi gerektiğini belirtir. |
critical | Kodun aynı anda yalnızca bir iş parçacığında yürütüldüğünü belirtir. |
barrier | Ekipteki tüm iş parçacıklarını eşitler; tüm iş parçacıkları bariyeri yürütene kadar bariyerde duraklatılır. |
atomic | Atomik olarak güncelleştirilecek bir bellek konumunu belirtir. |
Flush | Tüm iş parçacıklarının tüm paylaşılan nesneler için aynı bellek görünümüne sahip olduğunu belirtir. |
Sipariş | Paralelleştirilmiş for döngü altındaki kodun sıralı döngü gibi yürütülmesi gerektiğini belirtir. |
Veri ortamı için:
Yönerge | Tanım |
---|---|
threadprivate | Bir değişkenin iş parçacığı için özel olduğunu belirtir. |
atomic
Atomik olarak güncelleştirilecek bir bellek konumunu belirtir.
#pragma omp atomic
expression
Parametreler
Ifa -de
Bellek konumunu birden fazla yazma işlemine karşı korumak istediğiniz lvalue değerini içeren deyim.
Açıklamalar
yönergesi atomic
hiçbir yan tümceyi desteklemez.
Daha fazla bilgi için bkz . 2.6.4 atomik yapısı.
Örnek
// omp_atomic.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
#define MAX 10
int main() {
int count = 0;
#pragma omp parallel num_threads(MAX)
{
#pragma omp atomic
count++;
}
printf_s("Number of threads: %d\n", count);
}
Number of threads: 10
barrier
Ekipteki tüm iş parçacıklarını eşitler; tüm iş parçacıkları bariyeri yürütene kadar bariyerde duraklatılır.
#pragma omp barrier
Açıklamalar
yönergesi barrier
hiçbir yan tümceyi desteklemez.
Daha fazla bilgi için bkz . 2.6.3 bariyer yönergesi.
Örnek
kullanma barrier
örneği için bkz . master.
critical
Kodun aynı anda yalnızca bir iş parçacığında yürütüldüğünü belirtir.
#pragma omp critical [(name)]
{
code_block
}
Parametreler
Adı
(İsteğe bağlı) Kritik kodu tanımlamak için bir ad. Ad parantez içine alınmalıdır.
Açıklamalar
yönergesi critical
hiçbir yan tümceyi desteklemez.
Daha fazla bilgi için bkz . 2.6.2 kritik yapısı.
Örnek
// omp_critical.cpp
// compile with: /openmp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int i;
int max;
int a[SIZE];
for (i = 0; i < SIZE; i++)
{
a[i] = rand();
printf_s("%d\n", a[i]);
}
max = a[0];
#pragma omp parallel for num_threads(4)
for (i = 1; i < SIZE; i++)
{
if (a[i] > max)
{
#pragma omp critical
{
// compare a[i] and max again because max
// could have been changed by another thread after
// the comparison outside the critical section
if (a[i] > max)
max = a[i];
}
}
}
printf_s("max = %d\n", max);
}
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
max = 29358
flush
Tüm iş parçacıklarının tüm paylaşılan nesneler için aynı bellek görünümüne sahip olduğunu belirtir.
#pragma omp flush [(var)]
Parametreler
var
(İsteğe bağlı) Eşitlemek istediğiniz nesneleri temsil eden değişkenlerin virgülle ayrılmış listesi. var belirtilmezse, tüm bellek boşaltılır.
Açıklamalar
yönergesi flush
hiçbir yan tümceyi desteklemez.
Daha fazla bilgi için bkz . 2.6.5 temizleme yönergesi.
Örnek
// omp_flush.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
void read(int *data) {
printf_s("read data\n");
*data = 1;
}
void process(int *data) {
printf_s("process data\n");
(*data)++;
}
int main() {
int data;
int flag;
flag = 0;
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
{
printf_s("Thread %d: ", omp_get_thread_num( ));
read(&data);
#pragma omp flush(data)
flag = 1;
#pragma omp flush(flag)
// Do more work.
}
#pragma omp section
{
while (!flag) {
#pragma omp flush(flag)
}
#pragma omp flush(data)
printf_s("Thread %d: ", omp_get_thread_num( ));
process(&data);
printf_s("data = %d\n", data);
}
}
}
Thread 0: read data
Thread 1: process data
data = 2
için
Paralel bölge içindeki bir for
döngüde yapılan işin iş parçacıkları arasında bölünmesine neden olur.
#pragma omp [parallel] for [clauses]
for_statement
Parametreler
Yan tümce
(İsteğe bağlı) Sıfır veya daha fazla yan tümce, Açıklamalar bölümüne bakın.
for_statement
Bir for
döngü. Döngüdeki kullanıcı kodu dizin değişkenini for
değiştirirse tanımsız davranış ortaya çıkar.
Açıklamalar
yönergesi for
aşağıdaki yan tümceleri destekler:
Ayrıca belirtilirseparallel
, clauses
dışında nowait
veya for
yönergeleri tarafından parallel
kabul edilen herhangi bir yan tümce olabilir.
Daha fazla bilgi için bkz . yapı için 2.4.1.
Örnek
// omp_for.cpp
// compile with: /openmp
#include <stdio.h>
#include <math.h>
#include <omp.h>
#define NUM_THREADS 4
#define NUM_START 1
#define NUM_END 10
int main() {
int i, nRet = 0, nSum = 0, nStart = NUM_START, nEnd = NUM_END;
int nThreads = 0, nTmp = nStart + nEnd;
unsigned uTmp = (unsigned((abs(nStart - nEnd) + 1)) *
unsigned(abs(nTmp))) / 2;
int nSumCalc = uTmp;
if (nTmp < 0)
nSumCalc = -nSumCalc;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel default(none) private(i) shared(nSum, nThreads, nStart, nEnd)
{
#pragma omp master
nThreads = omp_get_num_threads();
#pragma omp for
for (i=nStart; i<=nEnd; ++i) {
#pragma omp atomic
nSum += i;
}
}
if (nThreads == NUM_THREADS) {
printf_s("%d OpenMP threads were used.\n", NUM_THREADS);
nRet = 0;
}
else {
printf_s("Expected %d OpenMP threads, but %d were used.\n",
NUM_THREADS, nThreads);
nRet = 1;
}
if (nSum != nSumCalc) {
printf_s("The sum of %d through %d should be %d, "
"but %d was reported!\n",
NUM_START, NUM_END, nSumCalc, nSum);
nRet = 1;
}
else
printf_s("The sum of %d through %d is %d\n",
NUM_START, NUM_END, nSum);
}
4 OpenMP threads were used.
The sum of 1 through 10 is 55
master
Yalnızca ana iş parçacığının programın bir bölümünü yürütmesi gerektiğini belirtir.
#pragma omp master
{
code_block
}
Açıklamalar
yönergesi master
hiçbir yan tümceyi desteklemez.
Daha fazla bilgi için bkz . 2.6.1 ana yapısı.
Kodun bir bölümünün ana iş parçacığı değil, tek bir iş parçacığında yürütülmesi gerektiğini belirtmek için bunun yerine tek yönergesini kullanın.
Örnek
// compile with: /openmp
#include <omp.h>
#include <stdio.h>
int main( )
{
int a[5], i;
#pragma omp parallel
{
// Perform some computation.
#pragma omp for
for (i = 0; i < 5; i++)
a[i] = i * i;
// Print intermediate results.
#pragma omp master
for (i = 0; i < 5; i++)
printf_s("a[%d] = %d\n", i, a[i]);
// Wait.
#pragma omp barrier
// Continue with the computation.
#pragma omp for
for (i = 0; i < 5; i++)
a[i] += i;
}
}
a[0] = 0
a[1] = 1
a[2] = 4
a[3] = 9
a[4] = 16
ordered
Paralelleştirilmiş for
döngü altındaki kodun sıralı döngü gibi yürütülmesi gerektiğini belirtir.
#pragma omp ordered
structured-block
Açıklamalar
yönergesi ordered
, bir için veya parallel for
yan tümcesi ile ordered
yapısının dinamik kapsamı içinde olmalıdır.
yönergesi ordered
hiçbir yan tümceyi desteklemez.
Daha fazla bilgi için bkz . 2.6.6 sıralı yapısı.
Örnek
// omp_ordered.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
static float a[1000], b[1000], c[1000];
void test(int first, int last)
{
#pragma omp for schedule(static) ordered
for (int i = first; i <= last; ++i) {
// Do something here.
if (i % 2)
{
#pragma omp ordered
printf_s("test() iteration %d\n", i);
}
}
}
void test2(int iter)
{
#pragma omp ordered
printf_s("test2() iteration %d\n", iter);
}
int main( )
{
int i;
#pragma omp parallel
{
test(1, 8);
#pragma omp for ordered
for (i = 0 ; i < 5 ; i++)
test2(i);
}
}
test() iteration 1
test() iteration 3
test() iteration 5
test() iteration 7
test2() iteration 0
test2() iteration 1
test2() iteration 2
test2() iteration 3
test2() iteration 4
parallel
Birden çok iş parçacığı tarafından paralel olarak yürütülecek olan bir paralel bölge tanımlar.
#pragma omp parallel [clauses]
{
code_block
}
Parametreler
Yan tümce
(İsteğe bağlı) Sıfır veya daha fazla yan tümce, Açıklamalar bölümüne bakın.
Açıklamalar
yönergesi parallel
aşağıdaki yan tümceleri destekler:
parallel
ve bölümleri yönergeleriyle de kullanılabilir.
Daha fazla bilgi için bkz . 2.3 paralel yapısı.
Örnek
Aşağıdaki örnek, iş parçacığı sayısını ayarlamayı ve paralel bir bölge tanımlamayı gösterir. İş parçacığı sayısı, varsayılan olarak makinedeki mantıksal işlemci sayısına eşittir. Örneğin, hiper iş parçacığı kullanımı etkinleştirilmiş bir fiziksel işlemciye sahip bir makineniz varsa, iki mantıksal işlemciye ve iki iş parçacığına sahip olur. Çıkışın sırası farklı makinelerde farklılık gösterebilir.
// omp_parallel.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
printf_s("Hello from thread %d\n", i);
}
}
Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3
sections
Tüm iş parçacıkları arasında bölünecek kod bölümlerini tanımlar.
#pragma omp [parallel] sections [clauses]
{
#pragma omp section
{
code_block
}
}
Parametreler
Yan tümce
(İsteğe bağlı) Sıfır veya daha fazla yan tümce, Açıklamalar bölümüne bakın.
Açıklamalar
yönergesi sections
sıfır veya daha fazla section
yönerge içerebilir.
yönergesi sections
aşağıdaki yan tümceleri destekler:
Ayrıca belirtilirseparallel
, clauses
dışında nowait
veya sections
yönergeleri tarafından parallel
kabul edilen herhangi bir yan tümce olabilir.
Daha fazla bilgi için bkz . 2.4.2 bölüm yapısı.
Örnek
// omp_sections.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel sections num_threads(4)
{
printf_s("Hello from thread %d\n", omp_get_thread_num());
#pragma omp section
printf_s("Hello from thread %d\n", omp_get_thread_num());
}
}
Hello from thread 0
Hello from thread 0
single
Kodun bir bölümünün ana iş parçacığında değil, tek bir iş parçacığında yürütülmesi gerektiğini belirtmenize olanak tanır.
#pragma omp single [clauses]
{
code_block
}
Parametreler
Yan tümce
(İsteğe bağlı) Sıfır veya daha fazla yan tümce, Açıklamalar bölümüne bakın.
Açıklamalar
yönergesi single
aşağıdaki yan tümceleri destekler:
Daha fazla bilgi için bkz . 2.4.3 tek yapı.
Bir kod bölümünün yalnızca ana iş parçacığında yürütülmesi gerektiğini belirtmek için bunun yerine ana yönergesini kullanın.
Örnek
// omp_single.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
int main() {
#pragma omp parallel num_threads(2)
{
#pragma omp single
// Only a single thread can read the input.
printf_s("read input\n");
// Multiple threads in the team compute the results.
printf_s("compute results\n");
#pragma omp single
// Only a single thread can write the output.
printf_s("write output\n");
}
}
read input
compute results
compute results
write output
threadprivate
Bir değişkenin iş parçacığı için özel olduğunu belirtir.
#pragma omp threadprivate(var)
Parametreler
var
İş parçacığında özel hale getirmek istediğiniz değişkenlerin virgülle ayrılmış listesi. var , genel veya ad alanı kapsamlı bir değişken veya yerel statik değişken olmalıdır.
Açıklamalar
yönergesi threadprivate
hiçbir yan tümceyi desteklemez.
yönergesithreadprivate
, __declspec anahtar sözcüğünü kullanan iş parçacığı özniteliğini temel alır; üzerindeki __declspec(thread)
sınırlar için threadprivate
geçerlidir. Örneğin, yalnızca threadprivate
paralel bölge tarafından oluşturulan bir iş parçacığı ekibinin parçası olan iş parçacıklarında değil, işlemde başlatılan herhangi bir iş parçacığında bir değişken bulunur. Bu uygulama ayrıntılarına dikkat edin; Kullanıcı tanımlı bir threadprivate
tür için oluşturucuların daha sık çağrıldığını ve daha sonra beklendiğini fark edebilirsiniz.
İşlem başlangıcında statik olarak yüklenen bir DLL'de kullanabilirsinizthreadprivate
, ancak aynı zamanda kullanan LoadLibrary
/DELAYLOAD (gecikme yükü içeri aktarma) ile yüklenen DLL'ler gibi LoadLibrary aracılığıyla yüklenecek dll'lerde kullanamazsınızthreadprivate
.
threadprivate
Yok edilebilir türde bir değişkenin yıkıcısının çağrıldığı garanti edilemez. Örnek:
struct MyType
{
~MyType();
};
MyType threaded_var;
#pragma omp threadprivate(threaded_var)
int main()
{
#pragma omp parallel
{}
}
Kullanıcıların paralel bölgeyi oluşturan iş parçacıklarının ne zaman sonlandırılacağı konusunda hiçbir denetimi yoktur. İşlemden çıkıldığında bu iş parçacıkları varsa, iş parçacıklarına işlem çıkışı hakkında bildirim gösterilmez ve çıkış yapan iş parçacığı (burada birincil iş parçacığı) dışında herhangi bir iş parçacığında yıkıcı çağrılmaz threaded_var
. Bu nedenle kod, değişkenlerin doğru şekilde yok edilmesine threadprivate
bağlı olmamalıdır.
Daha fazla bilgi için bkz . 2.7.1 threadprivate yönergesi.
Örnek
kullanma threadprivate
örneği için bkz . özel.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin