我正在大学学习SYCL,我有一个关于代码性能的问题。特别是我有这个C/C++代码:

我需要在一个带有并行化的SYCL内核中翻译它,我这样做:
#include <sycl/sycl.hpp>
#include <vector>
#include <iostream>
using namespace sycl;
constexpr int size = 131072; // 2^17
int main(int argc, char** argv) {
//Create a vector with size elements and initialize them to 1
std::vector<float> dA(size);
try {
queue gpuQueue{ gpu_selector{} };
buffer<float, 1> bufA(dA.data(), range<1>(dA.size()));
gpuQueue.submit([&](handler& cgh) {
accessor inA{ bufA,cgh };
cgh.parallel_for(range<1>(size),
[=](id<1> i) { inA[i] = inA[i] + 2; }
);
});
gpuQueue.wait_and_throw();
}
catch (std::exception& e) { throw e; }所以我的问题是关于c值,在这个例子中,我直接使用了值2,但是这会影响我在运行代码时的性能?我需要创建一个变量,或者这样做是正确的,性能是好的?
提前感谢您的帮助!
发布于 2022-07-01 08:02:22
有趣的问题。在这种情况下,值2将是您的SYCL内核中的指令中的一个文字--我认为这是非常有效的!从int到float有一个隐式转换,这是一个轻微的复杂问题。我的猜测是,您可能最终会在设备程序集中得到一个float文本2.0。您的SYCL设备不必从内存中获取该2,也不必在运行时进行强制转换或类似的操作,它只存在于指令中。
同样,如果你有:
constexpr int c = 2;
// the rest of your code
[=](id<1> i) { inA[i] = inA[i] + c; }
// etc编译器几乎肯定足够聪明,能够将c的常量值传播到内核代码中。因此,同样,2.0文本在指令中结束。
我用DPC++编译了您的示例并提取了LLVM,并找到了以下几行:
%5 = load float, float addrspace(4)* %arrayidx.ascast.i.i, align 4, !tbaa !17
%add.i = fadd float %5, 2.000000e+00
store float %add.i, float addrspace(4)* %arrayidx.ascast.i.i, align 4, !tbaa !17这显示了一个浮动加载&存储到/从同一个地址,中间有一个'add 2.0‘指令。如果像我演示的那样修改以使用变量c,就会得到相同的LLVM。
结论:您已经实现了最大的效率,编译器是聪明的!
https://stackoverflow.com/questions/72818234
复制相似问题