任务非常简单,将整数变量的序列写入内存:
原始代码:
for (size_t i=0; i<1000*1000*1000; ++i)
{
data[i]=i;
};
Run Code Online (Sandbox Code Playgroud)
并行化代码:
size_t stepsize=len/N;
#pragma omp parallel num_threads(N)
{
int threadIdx=omp_get_thread_num();
size_t istart=stepsize*threadIdx;
size_t iend=threadIdx==N-1?len:istart+stepsize;
#pragma simd
for (size_t i=istart; i<iend; ++i)
x[i]=i;
};
Run Code Online (Sandbox Code Playgroud)
性能很糟糕,编写1G 变量(每秒等于5GB)需要1.6秒uint64
,通过open mp parallel
上面代码的简单并行化(),速度提升升级,但性能仍然很糟糕,4线程和1.35 需要1.4秒在i7 3970上有6个线程.
我的装备(i7 3970/64G DDR3-1600)的理论内存带宽是51.2 GB /秒,对于上面的例子,实现的内存带宽只是大约带宽的1/10,即使应用程序也是相当多的内存-bandwidth有界.
有谁知道如何改进代码?
我在GPU上写了很多内存绑定代码,GPU很容易充分利用GPU的设备内存带宽(例如85%+的带宽).
编辑:
该代码由Intel ICC 13.1编译为64位二进制文件,并具有最大优化(O3)和AVX代码路径,以及自动矢量化.
更新:
我尝试了下面的所有代码(感谢Paul R),没有什么特别的事情发生,我相信编译器完全有能力进行simd /矢量化优化.
至于我为什么要在那里填写数字,好吧,长话短说:
它是高性能异构计算算法的一部分,在设备方面,algorthim非常高效,以至于多GPU集如此之快,以至于我发现性能瓶颈恰好是当CPU尝试写几个序列时数字到记忆.
原因,知道CPU在填充数(相反抽吸中,GPU可在非常接近(速度补数的seqence 238GB /秒总分288GB /秒上GK110 VS可怜5GB /秒总分 …
对一段代码进行一些优化,代码的正确性取决于编译器如何处理NaN.
我阅读了关于NaN的IEEE-754规则,其中规定:
比较EQ,GT,GE,LT和LE,当其中一个或两个操作数为NaN时返回FALSE.
比较NE,当其中一个或两个操作数为NaN时返回TRUE.
上述规则是否在C/C++中实施?
考虑以下代码,是否可以安全地进行指针运算nullptr
?
我假设nullptr
在另一个结果中添加任何偏移nullptr
,到目前为止MSVC产生的结果与我预期的一样,但是我有点不确定这样使用是否nullptr
安全:
float * x = nullptr;
float * y = x + 31; // I assume y is a nullptr after this assigment
if (y != nullptr)
{
/* do something */
}
Run Code Online (Sandbox Code Playgroud) NVIDIA GPU是否支持无序执行?
我的第一个猜测是它们不包含如此昂贵的硬件.但是,在阅读时CUDA progamming guide
,指南建议使用指令级并行(ILP)来提高性能.
ILP不是支持乱序执行的硬件可以利用的功能吗?或者NVIDIA的ILP仅仅意味着编译器级别的指令重新排序,因此它的顺序在运行时仍然是固定的.换句话说,只是编译器和/或程序员必须以这样的方式安排指令的顺序,即通过按顺序执行可以在运行时实现ILP?
如果我在 Ubuntu 上得到一些由 GCC 4.8 构建的 C++ 代码,该代码没有 GUI/界面,仅调用标准 Linux 库,那么该二进制文件可以在 RHEL 5/6 上完美运行,并且可以与更旧的 GCC 一起完美运行吗?
cudaMemcpy(dst, src, filesize, cudaMemcpyDeviceToHost);
Run Code Online (Sandbox Code Playgroud)
filesize
存储在设备全局存储器中的变量在哪里.
在 CUDA 中,流 0 与其他流有何关系?流 0(默认流)是否与上下文中的其他流同时执行?
考虑以下示例:
cudaMemcpy(Dst, Src, sizeof(float)*datasize, cudaMemcpyHostToDevice);//stream 0;
cudaStream_t stream1;
/...creating stream1.../
somekernel<<<blocks, threads, 0, stream1>>>(Dst);//stream 1;
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,编译器能否确保始终在完成后somekernel
启动或与 并发执行? cudaMemcpy
somekernel
cudaMemcpy
我知道模板定义及其实现可以并且必须放在一起,但是(非模板)类怎么样?
就个人而言,我更喜欢把类和它的实现放在一起,如果可能的话,因为它使用起来比较简单,你只需要在项目中包含头文件,不需要打扰实现文件.
你们有多少人在你的项目中广泛使用STL?
我从来没有使用STL的东西,其中一个,我不是一个专业的程序员,只是在需要时为高性能计算应用程序编写一些程序/库的人,对我来说,我认为STL并不是特别有用:
1,它提供了一些功能,如排序,哈希表,二叉树,但实现通常不是很好,在性能方面也不好,我可以很容易地找到替换或自己编写,性能更好,有时甚至更好.
2,它提供了一些我自己可以轻松编写的容器.
3,它使用了大量的C++结构/ warppers/grammars,它真正花费了我学习和掌握它的时间.
因此,当项目中有很多程序员需要一致的编程接口时,我可以说STL仅用于高效编程吗?我不应该为我的应用程序烦恼吗?