Cuda L2传输开销
我有一个内核,可以用Cuda L2传输开销,cuda,disassembly,nsight,ldg,Cuda,Disassembly,Nsight,Ldg,我有一个内核,可以用atomicMin测试渲染点。测试设置在idea案例内存布局中有大量的点。两个缓冲区,一个用于256x集群的uint32 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::u
atomicMin
测试渲染点。测试设置在idea案例内存布局中有大量的点。两个缓冲区,一个用于256x集群的uint32
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如下所示:
查看内存分析器输出:从点::Packed*
缓冲区读取的L2传输开销是3.0这是为什么?内存应该完全对齐并按顺序排列。另外,为什么会自动生成LDG
(计算50,sm 50)?我不需要缓存它。在L2传输开销的工具提示中,它说它测量“L1中每个请求字节在L1和L2之间实际传输的字节数”,还说“越低越好”
在我的例子中,读取Point::Packed
的二级传输开销是1.0
测试代码
namespace Point
{
struct PackedBitfield
{
uint32_t x : 6;
uint32_t y : 6;
uint32_t z : 6;
uint32_t nx : 4;
uint32_t ny : 4;
uint32_t nz : 4;
uint32_t unused : 2;
};
union __align__(4) Packed
{
uint32_t bits;
PackedBitfield field;
};
struct ClusterPositionBitfield
{
uint32_t x : 10;
uint32_t y : 10;
uint32_t z : 10;
uint32_t w : 2;
};
union ClusterPosition
{
uint32_t bits;
ClusterPositionBitfield field;
};
}
__global__ void pointsRenderKernel(Point::Packed* points, Point::ClusterPosition* clusterPosition)
{
int t_id = blockIdx.x * blockDim.x + threadIdx.x;
clusterPosition[blockIdx.x + blockDim.x] = clusterPosition[blockIdx.x];
points[t_id + blockDim.x * gridDim.x] = points[t_id];
}
void main()
{
int blockSize = 256;
int numberOfClusters = 256;
std::cout << sizeof(Point::Packed) << std::endl;
std::cout << sizeof(Point::ClusterPosition) << std::endl;
Point::Packed *d_points;
cudaMalloc(&d_points, sizeof(Point::Packed) * numberOfClusters * blockSize * 2);
Point::ClusterPosition *d_clusterPositions;
cudaMalloc(&d_points, sizeof(Point::ClusterPosition) * numberOfClusters * 2);
pointsRenderKernel<<<numberOfClusters, blockSize>>>(d_points, d_clusterPositions);
}
名称空间点
{
结构PackedBitfield
{
uint32_t x:6;
uint32_t y:6;
uint32_t z:6;
uint32_t nx:4;
uint32_t ny:4;
uint32_t nz:4;
uint32未使用:2;
};
活接头对齐(4)已包装
{
uint32_t位;
PackedBitfield字段;
};
结构ClusterPositionBitfield
{
uint32_t x:10;
uint32年:10;
uint32_t z:10;
uint32_t w:2;
};
联合集群定位
{
uint32_t位;
ClusterPositionBitfield字段;
};
}
__全局无效点内核(点::压缩*点,点::簇位置*簇位置)
{
int t_id=blockIdx.x*blockDim.x+threadIdx.x;
clusterPosition[blockIdx.x+blockDim.x]=clusterPosition[blockIdx.x];
点[t_id+blockDim.x*gridDim.x]=点[t_id];
}
void main()
{
int blockSize=256;
int numberOfClusters=256;
std::cout对于只读数据,LDG
使用的加载路径通常是最有效的,因此CUDA工具链更倾向于使用该路径。对于我们这些没有该分析器的人(我想是Windows版本吧?)您能提到中给出的开销是多少吗?@einpoklum-开销是获取数据所需的内存事务的倍数。分析器也存在于Linux中(我相信基于Eclipse的除外)@njuffa-编译器生成什么类型的指令不是我的问题。我们没有看到完整的代码,只有…使用点并写入缓冲区…
,只有程序集的前10.8行。您只显示了您认为相关的内容,这显然毫无意义。请提供一个。哇,感谢您花时间尝试事实上,这两个问题和答案都是可以接受的,我们都需要发布确切的编译器标志。@ FHoNeg我以前也有一些问题,英伟达图形驱动程序固定了这个问题,如回答中提到的。你得到与计算5的结果相同吗?SM 5?@ FHONEIG,是的,VALU。L2传输开销的e值为1.0
,同样,当使用compute_50、sm_50编译时。虽然这不是一个真正的直接答案,但我假设这是旧版本Nsight上的一个测量错误。