Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Menyediakan tautan ke arahan yang digunakan dalam API OpenMP.
Visual C++ mendukung arahan OpenMP berikut.
Untuk berbagi kerja paralel:
| Directive | Description |
|---|---|
| parallel | Mendefinisikan wilayah paralel, yang merupakan kode yang akan dijalankan oleh beberapa utas secara paralel. |
| for | Menyebabkan pekerjaan yang dilakukan dalam perulangan for di dalam wilayah paralel dibagi di antara utas. |
| sections | Mengidentifikasi bagian kode yang akan dibagi di antara semua utas. |
| single | Memungkinkan Anda menentukan bahwa bagian kode harus dijalankan pada satu utas, belum tentu utas utama. |
Untuk alur utama dan sinkronisasi:
| Directive | Description |
|---|---|
| master | Menentukan bahwa hanya utas utama yang harus menjalankan bagian program. |
| critical | Menentukan bahwa kode hanya dijalankan pada satu utas pada satu waktu. |
| barrier | Menyinkronkan semua utas dalam tim; semua utas berhenti sejenak di penghubung, sampai semua utas menjalankan penghubung. |
| atomic | Menentukan bahwa lokasi memori akan diperbarui secara atomik. |
| flush | Menentukan bahwa semua utas memiliki tampilan memori yang sama untuk semua objek bersama. |
| ordered | Menentukan bahwa kode di bawah perulangan paralel for harus dijalankan seperti perulangan berurutan. |
Untuk lingkungan data:
| Directive | Description |
|---|---|
| threadprivate | Menentukan bahwa variabel bersifat privat ke utas. |
atomic
Menentukan bahwa lokasi memori yang akan diperbarui secara atomik.
#pragma omp atomic
expression
Parameters
expression
Pernyataan yang memiliki lvalue, yang lokasi memorinya ingin Anda lindungi dari lebih dari satu tulisan.
Remarks
Direktif atomic tidak mendukung klausa.
Untuk informasi selengkapnya, lihat konstruksi atom 2.6.4.
Example
// 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
Menyinkronkan semua utas dalam tim; semua utas berhenti sejenak di penghubung, sampai semua utas menjalankan penghubung.
#pragma omp barrier
Remarks
Direktif barrier tidak mendukung klausa.
Untuk informasi selengkapnya, lihat Direktif hambatan 2.6.3.
Example
Untuk sampel cara menggunakan barrier, lihat master.
critical
Menentukan bahwa kode hanya dijalankan pada satu utas pada satu waktu.
#pragma omp critical [(name)]
{
code_block
}
Parameters
name
(Opsional) Nama untuk mengidentifikasi kode penting. Nama harus diapit dalam tanda kurung.
Remarks
Direktif critical tidak mendukung klausa.
Untuk informasi selengkapnya, lihat konstruksi kritis 2.6.2.
Example
// 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
Menentukan bahwa semua utas memiliki tampilan memori yang sama untuk semua objek bersama.
#pragma omp flush [(var)]
Parameters
var
(Opsional) Daftar variabel yang dipisahkan koma yang mewakili objek yang ingin Anda sinkronkan. Jika var tidak ditentukan, semua memori akan dihapus.
Remarks
Direktif flush tidak mendukung klausa.
Untuk informasi selengkapnya, lihat direktif flush 2.6.5.
Example
// 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
for
Menyebabkan pekerjaan yang dilakukan dalam perulangan for di dalam wilayah paralel dibagi di antara utas.
#pragma omp [parallel] for [clauses]
for_statement
Parameters
clauses
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
for_statement
Sebuah for perulangan. Perilaku yang tidak ditentukan akan mengakibatkan jika kode pengguna dalam perulangan for mengubah variabel indeks.
Remarks
Direktif for mendukung klausul berikut:
Jika parallel juga ditentukan, clauses dapat berupa klausul apa pun yang diterima oleh atau parallel direktiffor, kecuali nowait.
Untuk informasi selengkapnya, lihat 2.4.1 untuk konstruksi.
Example
// 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
Menentukan bahwa hanya utas utama yang harus menjalankan bagian program.
#pragma omp master
{
code_block
}
Remarks
Direktif master tidak mendukung klausa.
Untuk informasi selengkapnya, lihat konstruksi master 2.6.1.
Untuk menentukan bahwa bagian kode harus dijalankan pada satu utas, belum tentu utas utama, gunakan direktif tunggal sebagai gantinya.
Example
// 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
Menentukan bahwa kode di bawah perulangan paralel for harus dijalankan seperti perulangan berurutan.
#pragma omp ordered
structured-block
Remarks
Direktif ordered harus berada dalam tingkat dinamis untuk atau parallel for membangun dengan ordered klausul.
Direktif ordered tidak mendukung klausa.
Untuk informasi selengkapnya, lihat konstruksi yang diurutkan 2.6.6.
Example
// 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
Mendefinisikan wilayah paralel, yang merupakan kode yang akan dijalankan oleh beberapa utas secara paralel.
#pragma omp parallel [clauses]
{
code_block
}
Parameters
clauses
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
Remarks
Direktif parallel mendukung klausul berikut:
parallel juga dapat digunakan dengan arahan untuk dan bagian .
Untuk informasi selengkapnya, lihat konstruksi paralel 2.3.
Example
Contoh berikut menunjukkan cara mengatur jumlah utas dan menentukan wilayah paralel. Jumlah utas sama secara default dengan jumlah prosesor logis pada komputer. Misalnya, jika Anda memiliki mesin dengan satu prosesor fisik yang mengaktifkan hyperthreading, itu akan memiliki dua prosesor logis dan dua utas. Urutan output dapat bervariasi pada komputer yang berbeda.
// 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
Mengidentifikasi bagian kode yang akan dibagi di antara semua utas.
#pragma omp [parallel] sections [clauses]
{
#pragma omp section
{
code_block
}
}
Parameters
clauses
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
Remarks
Direktif sections dapat berisi nol atau lebih section direktif.
Direktif sections mendukung klausul berikut:
Jika parallel juga ditentukan, clauses dapat berupa klausul apa pun yang diterima oleh atau parallel direktifsections, kecuali nowait.
Untuk informasi selengkapnya, lihat konstruksi bagian 2.4.2.
Example
// 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
Memungkinkan Anda menentukan bahwa bagian kode harus dijalankan pada satu utas, belum tentu utas utama.
#pragma omp single [clauses]
{
code_block
}
Parameters
clauses
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
Remarks
Direktif single mendukung klausul berikut:
Untuk informasi selengkapnya, lihat konstruksi tunggal 2.4.3.
Untuk menentukan bahwa bagian kode hanya boleh dijalankan pada utas utama, gunakan arahan master sebagai gantinya.
Example
// 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
Menentukan bahwa variabel bersifat privat ke utas.
#pragma omp threadprivate(var)
Parameters
var
Daftar variabel yang dipisahkan koma yang ingin Anda jadikan privat ke utas.
var harus berupa variabel cakupan global atau namespace atau variabel statis lokal.
Remarks
Direktif threadprivate tidak mendukung klausa.
Arahan didasarkan pada threadprivate menggunakan kata kunci __declspec; batasan berlaku untuk __declspec(thread).threadprivate Misalnya, threadprivate variabel akan ada di utas apa pun yang dimulai dalam proses, bukan hanya utas yang merupakan bagian dari tim utas yang dihasilkan oleh wilayah paralel. Perhatikan detail implementasi ini; Anda mungkin melihat bahwa konstruktor untuk jenis yang threadprivate ditentukan pengguna disebut lebih sering kemudian diharapkan.
Anda dapat menggunakan threadprivate dalam DLL yang dimuat secara statis saat startup proses, namun Anda tidak dapat menggunakan threadprivate di DLL apa pun yang akan dimuat melalui LoadLibrary seperti DLL yang dimuat dengan /DELAYLOAD (impor beban penundaan), yang juga menggunakan LoadLibrary.
threadprivate Variabel jenis yang dapat dihancurkan tidak dijamin memiliki destruktor yang dipanggil. For example:
struct MyType
{
~MyType();
};
MyType threaded_var;
#pragma omp threadprivate(threaded_var)
int main()
{
#pragma omp parallel
{}
}
Pengguna tidak memiliki kontrol kapan utas yang merupakan wilayah paralel akan berakhir. Jika utas tersebut ada ketika proses keluar, utas tidak akan diberi tahu tentang proses keluar, dan destruktor tidak akan dipanggil untuk threaded_var pada utas apa pun kecuali yang keluar (di sini, utas utama). Jadi kode tidak boleh mengandalkan threadprivate penghancuran variabel yang tepat.
Untuk informasi selengkapnya, lihat direktif threadprivate 2.7.1.
Example
Untuk sampel penggunaan threadprivate, lihat privat.