У меня есть ядро для проверки точек рендеринга с atomicMin
. У тестовой установки есть тонны точек в макете памяти случая. Два буфера, один uint32
для кластеров 256x uint32
.Накладные расходы Cuda L2
namespace Point
{
struct PackedBitfield
{
glm::uint32_t x : 6;
glm::uint32_t y : 6;
glm::uint32_t z : 6;
glm::uint32_t nx : 4;
glm::uint32_t ny : 4;
glm::uint32_t nz : 4;
glm::uint32_t unused : 2;
};
union __align__(4) Packed
{
glm::uint32_t bits;
PackedBitfield field;
};
struct ClusterPositionBitfield
{
glm::uint32_t x : 10;
glm::uint32_t y : 10;
glm::uint32_t z : 10;
glm::uint32_t w : 2;
};
union ClusterPosition
{
glm::uint32_t bits;
ClusterPositionBitfield field;
};
}
//
// launch with blockSize=(256, 1, 1) and grid=(numberOfClusters, 1, 1)
//
extern "C" __global__ void pointsRenderKernel(mat4 u_mvp,
ivec2 u_resolution,
uint64_t* rasterBuffer,
Point::Packed* points,
Point::ClusterPosition* clusterPosition)
{
// extract and compute world position
const Point::ClusterPosition cPosition(clusterPosition[blockIdx.x]);
const Point::Packed point(points[blockIdx.x*256 + threadIdx.x]);
...use points and write to buffer...
}
В результате SASS выглядит следующим образом:
Посмотрите на выходе профилировщика памяти: передача служебной L2 из Point::Packed*
буфера чтения является 3,0. Почему? Память должна быть идеально выровнена и последовательна. Также почему это автоматически генерирует LDG
(compute_50, sm_50)? Мне это не нужно кэшировать.
Для данных только для чтения 'LDG' использует путь загрузки, который, как правило, наиболее эффективен, поэтому инструментарий CUDA предпочитает использовать это. – njuffa
Для тех из нас, кто не имеет этого профилировщика (это версия Windows, которую я предполагаю?), Можете ли вы указать, какие единицы являются накладными расходами? – einpoklum
@einpoklum - накладные расходы являются краткими операциями памяти, необходимыми для извлечения данных. профайлер существует и в Linux (за исключением Eclipse, на котором я полагаю). – FHoenig