首先,可以根据http://www.cnblogs.com/zenny-chen/p/3816620.html来安装CUDA工具链。这个工具集里包含了CUDA编译器以及其它必要的工具。然后,我们进入/usr/local/cuda-6.0/samples/0_Simple 目录下找到最简单的vectorAdd文件夹,把它复制到你Home目录下的某个子目录下。然后,我们在命令行(terminal)使用cd命令进入此目录。注意,Ubuntu下可以直接把文件夹或文件拖进命令行,这样就把该文件夹或文件的绝对路径复制到命令行里了。

由于,我们使用Jetson的时候,往往会用CUDA,所以会跟CUDA一起编译连接。而CUDA的源文件(.cu)最终会被翻译为C++源文件(.cpp),而CUDA源文件里又不能使用连接存储指定符(Link Storage Specifier,比如extern "C"),因此,如果我们要使用汇编源文件的外部函数,必须得另写一个.cpp文件——C++源文件是可以通过extern "C"来找到C语言或汇编语言的外部符号的,在C++源文件里使用汇编源文件的外部函数。

因此,我们第一步是要在vectorAdd里新增两个文件,一个叫testASM.s(汇编源文件),一个叫hello.cpp(C++源文件)。

然后,我们编辑testASM.s:

 .text
.align .globl MyASMTest .thumb MyASMTest: add r0, r0, r1
vadd.i32 q0, q0, q0
bx lr

注意上述第6行,.thumb指示符,由于NVCC编译器默认使用Thumb-2指令集来编译所有源文件,而此工具链比较矬,不支持-mthumb-interwork编译选项,因此无法混编ARM与Thumb代码。因此,我们要么在汇编源文件里写.thumb,如果用.arm的话,那么得修改编译选项(后面会讲),把编译选项默认设置为ARM即可。

然后,我们看看hello.cpp的内容:

#include <stdio.h>

extern "C" int MyASMTest(int, int);

void HelloTest(void)
{
printf("The vaue is: %d\n", MyASMTest(, ));
}

最后,我们在默认的vectorAdd.cu源文件里,找到main函数最后的return 0;语句,在上面插入以下代码:

extern void HelloTest(void);

HelloTest();

这样,所有源文件都编辑好了。下面,我们需要修改makefile文件来把新增的源文件都参加编译与连接。

对于此MakeFile,我们从上到下来看:

首先,我们找到EXTRA_CCFLAGS这个符号,这里可以定义额外的编译选项。如果我们要把源文件都默认编译为ARM指令集,那么可以将其修改为:

EXTRA_CCFLAGS    ?= -marm

由于我们在汇编文件里动用了NEON指令集,因此我们需要增加-mfpu=neon命令,因此,我们可以这么加:

如果之前已经动用了?=,那么我们再添加使用+=。EXTRA_CCFLAGS ?= -mfpu=neon

然后,我们找到build: vectorAdd

我们复制vectorAdd.o:vectorAdd.cu以及下面的编译选项语句,然后粘贴到下一行(中间最好空一行,更容易查看),将vectorAdd.o改为testASM.o,把vectorAdd.cu改为testASM.s,然后编译选项不用动。

然后再粘贴一行,同样,把vectorAdd.o改为hello.o;把vectorAdd.cu改为hello.cpp。

OK,这样就把需要编辑的源文件都添加好了。后面再添加连接目标文件。在下一行,我们发现vectorAdd:  vectorAdd.o后面再把testASM.o与hello.o添加上即可——vectorAdd:  vectorAdd.o testASM.o hello.o

最后,我们在clean:里把需要清除的.o都加上,即上述的testASM.o hello.o。这样,我们就可以通过make clean很快把生成的目标文件都删除了。

这里顺带说一下,我们找到GCC这个符号,会看到默认采用g++。这样不管什么.c还是.cpp都会默认使用G++编译器来编译,即最后是C++文件。如果我们想编译为.c源文件(再加上支持C11标准),我们可以直接改用gcc。比如,我们再增加一个源文件,名字为pureC.c,内容如下:

int MySum(void)
{
int buffer[] = { [] = , [] = -, [] = , [] = - };
int sum = ;
for(int i = ; i < sizeof(buffer) / sizeof(buffer[]); i++)
sum += buffer[i]; return sum;
}

我们可以在hello.cpp中调用此函数。增加此源文件时,需要修改一下MakeFile,首先,我们在ALL_CCFLAGS符号定义下,ALL_LDFLAGS符号定义的上面插入以下makefile命令:

MY_CFLAGS := $(CCFLAGS)
MY_CFLAGS += $(EXTRA_CCFLAGS)
MY_CFLAGS += -std=gnu11

最下面的-std=gnu11就是启用了满足GNU规范的C11标准。然后,我们添加pureC.o:pureC.c

gcc $(INCLUDES) $(MY_CFLAGS) -o $@ -c $<

连接选项和make清除都一样加。这样,我们的PureC就能跑起来了。

最新文章

  1. 解析XML文档
  2. 采用MANIFEST.MF之jar报错ClassNotFoundException解法
  3. 1526. Martian Plates
  4. Guava学习笔记目录
  5. 【转】【Asp.Net】Asp.net发送邮件的两种方法小结
  6. android 全屏视频播放(SurfaceView + MediaPlayer)
  7. Python核心编程-闭包
  8. 支持向量机之Hinge Loss 解释
  9. Linux服务器集群系统(三)--转
  10. Objective-c中autorelease的释放时机
  11. 《sort帮你排序》-linux命令五分钟系列之二十六
  12. 面试题 46 1+ 2+3+...+n
  13. ubutun 下webalizer 分析Apache日志
  14. 每天一个linux命令(02):route命令
  15. Codeforces Round #486 (Div. 3) A. Diverse Team
  16. Python库,让你相见恨晚的第三方库
  17. 开源分布式搜索平台ELK(Elasticsearch+Logstash+Kibana)入门学习资源索引
  18. python 处理xml
  19. HDU 1686 Oulipo(优化的KMP)
  20. [会装]Hive安装(基于mysql数据库)

热门文章

  1. mysql 忘记/修改数据库密码
  2. mongodb的基本操作之更新不存在的数据
  3. ubuntu---记录.opencv多版本管理与切换
  4. 18 Candidates for the Top 10 Algorithms in Data Mining
  5. SimpleThreadPool极简版
  6. 关于Python中正则使用findall和分组的一个坑
  7. C语言——for循环和while循环的效率区别——类似哨兵思想
  8. map填充bean赋值,包括父类全部填充。
  9. PHP mysqli_character_set_name() 函数
  10. 分布式锁的三种实现方式 数据库、redis、zookeeper