Я пытаюсь изучить OpenMP, и наткнулся на тот факт, что потоки не сохраняют свои собственные данные при выполнении задач, а скорее имеют копию данных потока, который сгенерировал задачу.
«[T] Hreads не сохраняют свои собственные данные» - странный способ описать это. Приписывание владения данными самим потокам, а не задачам, которые они выполняют, является, пожалуй, ключевой концептуальной проблемой. Совершенно естественно, и следует ожидать, что поток, выполняющий заданную задачу, работает с и в среде данных этой задачи .
Но если вы не привыкли к явным задачам, то Понятно, что вы ушли так далеко, не оценивая различие здесь. (Многие) конструкции, которые приводят к неявным задачам, обычно структурированы таким образом, что не поддаются обнаружению различий.
Так что с вашим примером, да,
thread_id
внутри задачи относится к копии, которая назначена thread_id
потока, который создал задачу (т. е. тот, который выполняет единственную часть кода).
Хотя это может и не быть быть сразу очевидным, что следует из спецификации OMP:
Когда поток встречает конструкцию задачи, из кода для связанного структурированного блока генерируется явная задача. Среда данных задачи создается в соответствии с разделами атрибутов совместного использования данных в конструкции задачи, ICV среды для данных и любыми применяемыми по умолчанию значениями .
( Спецификация OMP 5.0, раздел 2.10.1 ; выделение добавлено)
Единственный способ, которым можно удовлетворить, - это если задача закрывается над какими-либо общими данными из контекста ее объявления, что действительно является вы наблюдаете Более того, это, как правило, то, что нужно - данные, с которыми должна работать задача , должны быть установлены в точке и в контексте ее объявления, иначе как можно указать, к чему относится задача? do?
Что если я хотел бы сослаться на собственные закрытые переменные исполняющего потока?
Потоки не имеют переменных, по крайней мере, не в терминология OMP. Они принадлежат «среде данных» любых задач, которые они выполняют в любой момент времени.
Являются ли они невосстановимыми тенями?
Когда поток выполняет заданную задачу , он обращается к среде данных этой задачи. Эта среда может включать переменные, которые используются совместно с другими задачами, но только в этом смысле она может обращаться к переменным другой задачи. «Неоправданно затененный» - это не та формулировка, которую я бы использовал для описания ситуации, но она дает представление о том, что нужно сделать. каждая строка?
Есть способы реструктурировать код для достижения этой цели, но ни один из них не так прост, как просто добавление предложения в директиву omp task
. На самом деле, я не думаю, что какой-либо из них вообще связан с явными задачами. Самый естественный способ получить это - параллель l oop:
#include <stdio.h>
#include <unistd.h>
#include <omp.h>
int main(void) {
#pragma omp parallel for num_threads(4)
for (int i = 0; i < 10; i++) {
int thread_id = omp_get_thread_num();
sleep(1);
printf("thread_id, ID of the executing thread: %d, %d\n", thread_id, omp_get_thread_num());
}
return 0;
}
Конечно, это также упрощает его до такой степени, что это кажется тривиальным, но, возможно, это помогает понять суть. Большая часть цели объявления явной задачи состоит в том, что эта задача может быть выполнена другим потоком, чем тот, который ее создал, и это именно то, чего вам нужно избегать, чтобы достичь требуемого поведения.