实习面试TOUTIAO

来源:互联网 发布:《简明python教程》 编辑:程序博客网 时间:2024/06/07 10:58
  1. 自我介绍,基本上就是把简历上的项目介绍一遍
  2. 一些基本知识
    (1)?gpu有哪些存储器
    寄存器 局部 共享 全局 常数 纹理
    register shared constant texture global
    ?host内存
    主机端内存 主机端页锁定内存
    host pinned
    ?__syncthread();同步block内部 还是block间
    !只有当整个线程块都走向相同分支时,才能在条件语句里边使用同步函数,否则引起错误。另外,一个warp内线程不用同步。
    !__syncthreads()实现了block内的线程同步,保证线程块中all thread 执行到同一位置。
    ?如果寄存器存不下怎么办 自动放在local memeory.(?)
    ? !kernel function 里边不加修饰的变量存在register/local memory中
    (2)怎样肉眼看出一个好的CUDA代码,怎样优化一个CUDA代码
    http://blog.csdn.net/zzconstantly/article/details/44656013
    https://segmentfault.com/a/1190000007540468
    http://blog.csdn.net/jolie_yang/article/details/52841421
    (3)?STL 中怎样表现hash
    !hash_map
    ?hash搜索 插入的时间复杂度
    查找索引当然会很快,不过只有无冲突的hash table复杂度才是O(1),一般是O(c),c为哈希关键字冲突时查找的平均长度;
    !hash表插入的时间复杂度是 同上;
    (4)? SOA ASO (http://blog.csdn.net/langb2014/article/details/51348636)

    !许多并行编程规范里,特别是SIMD-style风格的规范,都更倾向于使用SoA,在CUDA
    C里,SoA也是非常建议使用的,因为数据已经预先排序连续了 ———- Array of Structure versus
    Structure of Arrays 作为C程序员,我们应该熟悉两种组织数据的方式:array of
    structures(AoS)和structure of arrays(SoA)。二者的使用是一个有趣的话题,主要是数据排列组织。
    观察下面代码,首先考虑该数据结构集合在使用AoS组织时,是怎样存储的: [cpp] view plain copy
    在CODE上查看代码片派生到我的代码片 struct innerStruct {

    float x;  float y;   };   struct innerStruct myAoS[N]; //每一对x和y的存储,空间上是连续的  

    然后是SoA: [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 struct innerArray {

    float x[N];  float y[N];   };   struct innerArray moa; //x和y是分别存储的,所有x和y是分别存储在两段不同的连续地址里。  

    下图显示了AoS和SoA在内存中的存储格式,当对x进行操作时,会导致一般的带宽浪费,因为在操作x时,y也会隐式的被load,而SoA的表现就要好得多,因为所有x都是相邻的。
    许多并行编程规范里,特别是SIMD-style风格的规范,都更倾向于使用SoA,在CUDA
    C里,SoA也是非常建议使用的,因为数据已经预先排序连续了。 Example:Simple Math with the AoS Data

查看load/store性能: [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 $ nvprof
–devices 0 –metrics gld_efficiency,gst_efficiency ./simpleMathSoA gld_efficiency 100.00% gst_efficiency 100.00%


(5)?CUDA Stream
!流:程序通过流来管理并发,每个流是按顺序执行的一系列操作;不同流之间乱序执行或者并行执行;定义是创建一个cudaStream_t对象;当使用两个流处理同一块存储时,必须使用pinned memory;
(6)? 变量 !建堆时间复杂度 O(n), 堆排序的时间复杂度O(nlogn)
? 线程和进程的区别

http://blog.csdn.net/yaosiming2011/article/details/44280797
http://blog.csdn.net/thisisbatman/article/details/23060525
!1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

2.关系 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行. 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

3.区别 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4)
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5)
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

4.优缺点 线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

?线程和OpenMP的区别 !–多线程与并行计算的关系:并行计算式多个线程运行在多个cpu上, 多线程是多个线程运行在一个cpu上
OpenMP管理多线程(http://www.cnblogs.com/xudong-bupt/p/3622101.html)
OpenMP介绍(http://download.csdn.net/detail/wuyusun1982/3063387?locationNum=4&fps=1)
?高性能和深度学习

  1. 2道代码题目。 (1)(说明思路)有向图 判断是否有环 打印每一个节点的深度 http://blog.csdn.net/memray/article/details/8021865
    先介绍一下无向图的判断算法,这个比较简单: 判断无向图中是否存在回路(环)的算法描述
    如果存在回路,则必存在一个子图,是一个环路。环路中所有顶点的度>=2。 算法:
    第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。
    第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。
    如果最后还有未删除顶点,则存在环,否则没有环。 算法分析:
    由于有m条边,n个顶点。如果m>=n,则根据图论知识可直接判断存在环路。

    (证明:如果没有环路,则该图必然是k棵树 k>=1。根据树的性质,边的数目m = n-k。k>=1,所以:m<n)        如果m<n 则按照上面的算法每删除一个度为0的顶点操作一次(最多n次),或每删除一个度为1的顶点(同时删一条边)操作一次(最多m次)。这两种操作的总数不会超过m+n。由于m<n,所以算法复杂度为O(n)

    接下来介绍有向图是否有环的判定算法,主要有深度优先和拓扑排序2中方法。
    1、拓扑排序,如果能够用拓扑排序完成对图中所有节点的排序的话,就说明这个图中没有环,而如果不能完成,则说明有环。
    2、可以用Strongly Connected Components来做,我们可以回忆一下强连通子图的概念,就是说对于一个图的某个子图,该子图中的任意u->v,必有v->u,则这是一个强连通子图。这个限定正好是环的概念。所以我想,通过寻找图的强连通子图的方法应该可以找出一个图中到底有没有环、有几个环。
    3、就是用一个改进的DFS
    刚看到这个问题的时候,我想单纯用DFS就可以解决问题了。但细想一下,是不能够的。如果题目给出的是一个无向图,那么OK,DFS是可以解决的。但无向图得不出正确结果的。比如:A->B,A->C->B,我们用DFS来处理这个图,我们会得出它有环,但其实没有。
    我们可以对DFS稍加变化,来解决这个问题。解决的方法如下:
    图中的一个节点,根据其C[N]的值,有三种状态:
    0,此节点没有被访问过
    -1,被访问过至少1次,其后代节点正在被访问中
    1,其后代节点都被访问过。
    按照这样的假设,当按照DFS进行搜索时,碰到一个节点时有三种可能:
    1、如果C[V]=0,这是一个新的节点,不做处理
    2、如果C[V]=-1,说明是在访问该节点的后代的过程中访问到该节点本身,则图中有环。
    3、如果C[V]=1,类似于2的推导,没有环。 在程序中加上一些特殊的处理,即可以找出图中有几个环,并记录每个环的路径

    上面这个算法我没看懂。。所以没实现,但是自己用DFS实现了环检测。

    (2)求和cuda代码
    vectorAdd()
    vectorAddDrv()
    Reduction()

0 0