我的CUDA程序正遭受未合并的全局内存访问.虽然第idx个线程只处理数组中的[idx] -th单元格,但是有许多间接内存访问,如下所示.
int idx=blockDim.x*blockIdx.x+threadIdx.x;
.... = FF[m_front[m_fside[idx]]];
Run Code Online (Sandbox Code Playgroud)
对于m_fisde [idx],我们已经合并了访问,但我们实际需要的是FF [m_front [m_fside [idx]]].有两级间接访问.
我试图在m_front或m_fsied中找到一些数据模式,以使其成为直接顺序访问,但发现它们几乎是"随机的".
有没有办法解决这个问题?
英特尔拥有多个SIMD ISA,如Xeon Phi上的SSE,AVX,AVX2,AVX-512和IMCI.这些ISA在不同的处理器上受支持.例如,AVX-512 BW,AVX-512 DQ和AVX-512 VL仅支持Skylake,但不支持Xeon Phi.Skylake和Xeon Phi均支持AVX-512F,AVX-512 CDI,AVX-512 ERI和AVX-512 PFI.
为什么英特尔不设计可以在其所有高级处理器上运行的更通用的SIMD ISA?
此外,英特尔在开发ISA时删除了一些内在函数并添加了新的内在函数.很多内在函数有很多种.例如,一些工作在打包的8位上,而一些工作在打包的64位上.有些口味没有得到广泛支持.例如,Xeon Phi无法处理打包的8位值.然而,Skylake将拥有此功能.
为什么英特尔以这种不一致的方式改变其SIMD内在函数?
如果SIMD ISA彼此更兼容,则现有的AVX代码可以轻松移植到AVX-512.
我在这里将一段 pthread 代码列为函数“thread”。它基本上创建许多线程(Xeon Phi 上通常为 240 个,CPU 上通常为 16 个),然后连接它们。
如果我只调用这个 thread() 一次,它在 CPU 和 Xeon Phi 上都能完美运行。如果我再调用一次,它在 CPU 上仍然可以正常工作,但 pthread_create() 将报告“错误 22”,每 60 个线程应该是“无效参数”。
例如,第二次运行 thread() 的线程 0、线程 60、线程 120 等(也是进程中曾经创建的 241、301、361 等线程)将失败(错误 22)。但线程 1~59、61~119、121~240 等可以正常工作。
请注意,此问题仅发生在 Xeon Phi 上。
我检查了堆栈大小和参数本身,但没有找到原因。论据是正确的。
void thread()
{
...
int i, rv;
cpu_set_t set;
arg_t args[nthreads];
pthread_t tid[nthreads];
pthread_attr_t attr;
pthread_barrier_t barrier;
rv = pthread_barrier_init(&barrier, NULL, nthreads);
if(rv != 0)
{
printf("Couldn't create the barrier\n");
exit(EXIT_FAILURE);
}
pthread_attr_init(&attr);
for(i = 0; i < …
Run Code Online (Sandbox Code Playgroud)