Arahan OpenMP
Menyediakan tautan ke arahan yang digunakan dalam API OpenMP.
Visual C++ mendukung arahan OpenMP berikut.
Untuk berbagi kerja paralel:
Direktif | Deskripsi |
---|---|
Paralel | Mendefinisikan wilayah paralel, yang merupakan kode yang akan dijalankan oleh beberapa utas secara paralel. |
Untuk | Menyebabkan pekerjaan yang dilakukan dalam perulangan for di dalam wilayah paralel dibagi di antara utas. |
Bagian | Mengidentifikasi bagian kode yang akan dibagi di antara semua utas. |
tunggal | Memungkinkan Anda menentukan bahwa bagian kode harus dijalankan pada satu utas, belum tentu utas utama. |
Untuk alur utama dan sinkronisasi:
Direktif | Deskripsi |
---|---|
master | Menentukan bahwa hanya utas utama yang harus menjalankan bagian program. |
Kritis | Menentukan bahwa kode hanya dijalankan pada satu utas pada satu waktu. |
Penghalang | Menyinkronkan semua utas dalam tim; semua utas berhenti sejenak di penghubung, sampai semua utas menjalankan penghubung. |
Atom | Menentukan bahwa lokasi memori yang akan diperbarui secara atomik. |
Flush | Menentukan bahwa semua utas memiliki tampilan memori yang sama untuk semua objek bersama. |
Memerintahkan | Menentukan bahwa kode di bawah perulangan paralel for harus dijalankan seperti perulangan berurutan. |
Untuk lingkungan data:
Direktif | Deskripsi |
---|---|
threadprivate | Menentukan bahwa variabel bersifat privat ke utas. |
Atom
Menentukan bahwa lokasi memori yang akan diperbarui secara atomik.
#pragma omp atomic
expression
Parameter
expression
Pernyataan yang memiliki lvalue, yang lokasi memorinya ingin Anda lindungi dari lebih dari satu tulisan.
Keterangan
Direktif atomic
tidak mendukung klausa.
Untuk informasi selengkapnya, lihat konstruksi atom 2.6.4.
Contoh
// 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
Keterangan
Direktif barrier
tidak mendukung klausa.
Untuk informasi selengkapnya, lihat Direktif hambatan 2.6.3.
Contoh
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
}
Parameter
nama
(Opsional) Nama untuk mengidentifikasi kode penting. Nama harus diapit dalam tanda kurung.
Keterangan
Direktif critical
tidak mendukung klausa.
Untuk informasi selengkapnya, lihat konstruksi kritis 2.6.2.
Contoh
// 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)]
Parameter
var
(Opsional) Daftar variabel yang dipisahkan koma yang mewakili objek yang ingin Anda sinkronkan. Jika var tidak ditentukan, semua memori akan dihapus.
Keterangan
Direktif flush
tidak mendukung klausa.
Untuk informasi selengkapnya, lihat direktif flush 2.6.5.
Contoh
// 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
untuk
Menyebabkan pekerjaan yang dilakukan dalam perulangan for
di dalam wilayah paralel dibagi di antara utas.
#pragma omp [parallel] for [clauses]
for_statement
Parameter
Klausul
(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.
Keterangan
Direktif for
mendukung klausul berikut:
Jika parallel
juga ditentukan, clauses
dapat berupa klausul apa pun yang diterima oleh atau for
direktifparallel
, kecuali nowait
.
Untuk informasi selengkapnya, lihat 2.4.1 untuk konstruksi.
Contoh
// 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
}
Keterangan
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.
Contoh
// 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
dipesan
Menentukan bahwa kode di bawah perulangan paralel for
harus dijalankan seperti perulangan berurutan.
#pragma omp ordered
structured-block
Keterangan
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.
Contoh
// 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
}
Parameter
Klausul
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
Keterangan
Direktif parallel
mendukung klausul berikut:
parallel
juga dapat digunakan dengan arahan untuk dan bagian .
Untuk informasi selengkapnya, lihat konstruksi paralel 2.3.
Contoh
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
Bagian
Mengidentifikasi bagian kode yang akan dibagi di antara semua utas.
#pragma omp [parallel] sections [clauses]
{
#pragma omp section
{
code_block
}
}
Parameter
Klausul
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
Keterangan
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 sections
direktifparallel
, kecuali nowait
.
Untuk informasi selengkapnya, lihat konstruksi bagian 2.4.2.
Contoh
// 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
tunggal
Memungkinkan Anda menentukan bahwa bagian kode harus dijalankan pada satu utas, belum tentu utas utama.
#pragma omp single [clauses]
{
code_block
}
Parameter
Klausul
(Opsional) Nol atau lebih klausa, lihat bagian Komentar .
Keterangan
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.
Contoh
// 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)
Parameter
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.
Keterangan
Direktif threadprivate
tidak mendukung klausa.
Arahan didasarkan pada atribut utas menggunakan kata kunci __declspec; batasan __declspec(thread)
berlaku untuk threadprivate
.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. Contohnya:
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.
Contoh
Untuk sampel penggunaan threadprivate
, lihat privat.
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk