blueyi's notes

Follow Excellence,Success will chase you!

0%

CUDA程序往往很难高度,特别是核函数出错时,甚至有些情况下核函数中内容访问错误时,运行程序之后系统返回的报错信息是free() error之类的错误,会严重误导错误查找过程。所以编写CUDA程序一定记得进行错误错误处理,多写几行代码,有可能省出很多的时间。假如自己的CUDA程序出现了各种奇葩、难以理解的错误,可以考虑加上错误处理,也许就柳岸花明了。
CUDA学习笔记最后的总结中刻意提到编写CUDA程序一定要做错误处理,但其中一直未提及如何进行错误处理,这里给补上。

Read more »

关于|准备

本为内容来源于《CUDA by Example.An Introduction to General-Purpose GPU Programming》学习整理,网上中英文版都有,其源码以及本文测试源码在github。部分内容来源于CUDA官方文档http://docs.nvidia.com/cuda以及其他网上相关资料,官方文档右上角的搜索不是非常好用,如果没有搜索到你所需要的关键字可以定位到所需文档后试试ctrl+f,例如dim3的概念。这里是一个中文版本的NVIDIA_CUDA_Programming_Guide_2.0Final
新人入坑看这里,系统学习强烈推荐直接看官方这份编程指南:http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html,本文后期补充的大量内容都来自该指南。
看完指南再看官方的进阶文档,最佳实践指南:http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/,这些看完你也就完全入门了,并且跟上了CUDA的最新技术发展。

Read more »

首先明确C++中引用或指针的动态类型(dynamic type)与静态类型(static type)可以不同是C++支持多态性(polymorphism)的根本所在。
四个概念:

  • 静态类型:就是对象声明时采用的类型,一旦确定就无法更改,编译期已经确定
  • 动态类型:通常是指一个指针或引用在调用时所指向的类型,可以理解为赋值号右侧对象的类型(当然采用直接赋值就是括号中的对象的类型),可以在运行时更改,在运行期决定
  • 静态绑定(static binding):又名前期绑定(early binding),绑定的是对象的静态类型,发生在编译期,即程序编译完成后就已经确定
  • 动态绑定(dynamic binding):又名后期绑定(late binding),绑定的是对象的动态类型,发生在运行期,即在运行期由当前的动态类型决定所需要调用的函数或属性
Read more »

本来只是为了从底层了解下堆和栈的区别,以及heap和free-store的区别,结果便引出了从源代码编译开始,直到可执行程序如何加载到内存,以及C/C++内存布局的问题,这里做个总结,主要参考C++ Internals :: Memory Layout
本文所使用的环境:

  • Ubuntu-14.04 x64 kernel 4.2.0-36-generic
  • GCC version 4.8.4

需要使用的其他工具:

  • c++filt – Demangle C++ and Java symbols.详情可以自行查看man手册

C++编译器通常进行以下4个步骤将源代码编译为可执行程序:

  • 预处理器的预处理阶段,替换#开头的内容
  • 编译器编译阶段,将预处理后的源程序处理成汇编源程序
  • 汇编器的汇编阶段,将汇编源程序汇编为可重定位的目标二进制程序
  • 连接器将可生定位的目标程序连接成为可执行的二进制目标程序

以下面这段代码的编译链接过程举例:

Read more »

本文所使用的环境:

  • Ubuntu-14.04 x64 kernel 4.2.0-36-generic
  • GCC version 4.8.4

需要用到的工具(都是系统自带的,以下是man的基本信息,详细信息可以直接查看man手册):

  • size - list section sizes and total size.可以列出section大小和总的大小,能够用于粗略估计,但不适合深度研究section大小
  • readelf - Displays information about ELF files.显示ELF文件的信息,readelf非常强大,能够显示出ELF非常多的信息
  • objdump - display information from object files. 显示object文件的信息,也就是目标文件,功能与readelf类似,但没有readelf强大,有些readelf可以显示的信息,它无法显示

如果对编译过程不甚了解,可以参看这里实例验证C/C++源代码如何变成程序的过程

Read more »

简介

线程块中线程总数的大小除了受到硬件中Max Threads Per block的限制,同时还要受到Streaming Multiprocessor、RegisterShared Memory的影响。这些条件的共同作用下可以获得一个相对更合适的block尺寸。当block尺寸太小时,将无法充分利用所有线程;当block尺寸太大时,如果线程需要的资源总和过多,CUDA将通过强制减少block数量来保证资源供应,同样无法利用所有线程。而grid的尺寸通常越大越好,当grid中的线程总数超过一次所能启动的并发线程总数时,过多的线程将以线程块为单位由CUDA进行新的调用,当然启动数量够用就可以了,以免浪费资源。

Read more »

docker run应该是我们日常使用docker中最常用,也最重要的命令。
命令格式如下:

1
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Read more »

由于种种原因我们可能无法正常连接到python的官方pip源,或者连接速度很慢,或者由于根证书的原因在安装包时会提示连接证书问题,可以通过修改pip的配置来修改为国内其他源,并信任相应的源,避免证书错误,提高包安装速度。

Read more »

记录Dockerfile的编写规则和用法

Dockerfile就是用于构建image的一系列命令和参数构成的脚本,通过docker build -t <image_name:tag> -f </path/to/Dockerfile> .来构建。

docker build命令从名为Dockerfile的文件和context来构建image,context是PATH(本地目录)或者URL(Git repository位置)处的文件。context会以递归方式处理,所以PATH的子目录和git的submodules都会处理,同样这里要小心用于作为PATH的目录最好不要有与镜像无关的文件,通常会新建一个空文件夹做为context的PATH。

PATH下的.dockerignore可以用于排除文件和目录。

构建工作由Docker守护进程运行,而不是docker的CLI,其中-t参数用于指定镜像的repository和tag,可以有多个-t-f指定Dockerfile的路径,最后的.表示上下文件环境为当前目录。

例如:

1
docker build -t blueyi/python-3.6:dev -f ~/docker/Dockerfile .
Read more »

在一个系统较老的centos(6.9)上编译安装gcc4.8.5,系统源里面带的是4.7.2,对C++11中的特性支持不完整,所以需要手动编译一份新版本。
以为会很简单,直接下载源码,根据readme配置相关依赖源码,然而最后还是编译的时候报错,所以记录下来。

Read more »