Ответ довольно прост: общее адресное пространство не имеет аппаратного представления.
Вы можете увидеть общее адресное пространство (AS) как логическое AS, где объединены все остальные AS. Например: следующие вызовы ядра и функция устройства, которая принимает указатель.
__device__ void bar(int* x){
*x = *x + 1;
}
__global__ void foo(int* x){
__shared__ int y[1];
bar(x);
bar(y);
}
Вы можете передать любой указатель на функцию. С точки зрения языка это не означает, что указатель находится в AS 1 (глобальный) или AS 3 (общий). В C++ (и CUDA C/C++) вам не нужно явно указывать AS. В OpenCL < 2.0, например, вы должны явно добавить модификатор к каждому указателю и должны предоставить функцию bar
, которая принимает конкретный указатель AS.
Что происходит в LLVM IR, то, что указатель ведьмы передается функции, получает отличную от команды addresspacecast
генератор AS. В PTX addresspacecast
представлен cvta
инструкции:
// convert const, global, local, or shared address to generic address
cvta.space.size p, a; // source address in register a
cvta.space.size p, var; // get generic address of var
cvta.space.size p, var+imm; // generic address of var+offset
// convert generic address to const, global, local, or shared address
cvta.to.space.size p, a;
.space = { .const, .global, .local, .shared };
.size = { .u32, .u64 };
Общие указатели отображаются в глобальную память, если она не падает в пределах области адресов, зарезервированную для другой AS. Аппаратное обеспечение вычитает начальный адрес AS из общего указателя для определения правильной области памяти.
Atomics являются хорошим примером:
atom{.space}.op.type d, [a], b;
atom{.space}.op.type d, [a], b, c;
Вы можете указать адресное пространство, или пусть аппаратные выбрать. Если вы хотите сгенерировать правильную атомную инструкцию без накладных расходов на вычитание указателя, фоновый сервер отвечает за возврат указателя обратно в правильное адресное пространство.
Отличный ответ! – talonmies
Итак, основываясь на вашем ответе, вы говорите, что если указатель находится в AS1 в LLVM IR, у нас нет способа узнать, поступит ли он в глобальную или общую и т. Д. Память, правильно? – cache
Если указатель находится в AS1, мы знаем, что он находится в глобальной памяти. Если он находится в AS0, то точно это знает только аппаратное обеспечение. См. AS0 как конкатенирование всех AS от 1 до 5. –