Cuda 共享内存算术运算指令级并行性

Cuda 共享内存算术运算指令级并行性,cuda,Cuda,在开普勒中,为了获得ILP,我们是否应该将操作数与共享内存分离?我不知道它(操作数为共享内存的算术运算)是否分为两个操作,一个是从共享内存加载到寄存器,然后在寄存器上执行操作,还是一个操作 因为在“编程大规模并行多处理器”一书中关于数据预取的第6部分中说,加载到共享内存由两部分组成(首先从全局内存到寄存器,然后从寄存器到共享内存) e、 g 这份声明会产生ILP吗 result1=opA[1]+opB[1]; // opA and opB in Shared mem, result1 in re

在开普勒中,为了获得ILP,我们是否应该将操作数与共享内存分离?我不知道它(操作数为共享内存的算术运算)是否分为两个操作,一个是从共享内存加载到寄存器,然后在寄存器上执行操作,还是一个操作

因为在“编程大规模并行多处理器”一书中关于数据预取的第6部分中说,加载到共享内存由两部分组成(首先从全局内存到寄存器,然后从寄存器到共享内存)

e、 g 这份声明会产生ILP吗

result1=opA[1]+opB[1]; // opA and opB in Shared mem, result1 in register
result2=opC[1]+opD[1];// opC and opD in Shared mem, result2 in register
还是我们应该像这样分解以生成ILP

temp1=opA[1]; temp2=opB[1];
temp3=opC[1];temp4=opD[1];//temp variable in register
result1=temp1+temp2;
result2=temp3+temp4;

在您的示例中,您不太可能看到改进,因为编译器可能会更好地处理这种情况(正如Robert Crovella在评论中所说)

不过,在某些情况下,这种方式的预取可能有助于隐藏一些延迟。如果要使用向量类型将多个回迁合并为单个回迁,从而更好地利用总线,则可能会看到改进

一个非常简单的例子:

float4 temp1 = A[0];
float4 temp2 = A[1];

result1 = temp1.x + temp1.y + temp1.z + temp1.w;
num = result1 * 3.14159;
result2 = temp2.x * num + temp2.y * num + temp2.z + temp2.w * num;
这将导致
result1
num
的计算能够在
temp2
的提取发生时进行,从而有助于隐藏一些提取延迟

这真的不是一个很好的例子,但希望你能大致了解一下。预取更适合的一种情况是在循环中执行某些操作。如果预取循环第一次迭代所需的第一组数据,则可以在为下一次迭代获取数据时执行循环内容,依此类推

这方面的一个简单示例:

float4 temp = A[0];
float sum = 0;
for( int i = 4; i < sizeA - 4; i+=4 ) {
    sum = temp.x + temp.y + temp.z + temp.w;
    temp = A[i];
}
float4 temp=A[0];
浮点数和=0;
对于(int i=4;i
编译器了解需要什么,并且可能比您更好地完成这些本地重新排列以实现最佳ILP。是的,您是对的,破坏指令会导致更糟糕的结果。