AMD GPU Driver Software Engineer_2008-11-02.
1.已知数列3、10、13、23、36……。第208个数除以5余数是多少?
2.求过点(2,-3,0)n=(10)
3.1/(1*2) 1/(2*3) …… 1/(n*(n 1)) ……。判断无限级数的收敛性。(10)
4.Expand out what the acronymsstand for in ISR,APC, and DPC in a MS windows environments. Give a brief descriptionof what each term means. (8’)
5.Explain what the OS does whilecreating a process in windows or Linux? (6’)
6.Programming. Function: convertan integer to a string in n-radix using ANSIC.Void*xtoa( int x, int radix, char *out){} (15’)
7.Programming: Using C programsthe function ‘memcpy’. Taking performance into consideration.Void *memcpy( void *dst, const void *src, unsigned int size). (10’)
8.Given two trees, return true ifthey are structurally identical.int sameTree( structnode *a, struct node *b). (10’)
9.What is the meaning of thekeyword of ‘violatile’ in C ? (8’)
10.英文题目,写一封信,大致内容:你对一个六个月的实习机会感兴趣,想申请,但需要教授的推荐信。Write him to ask for the reference letter. (15’)
1.ISR, APC, DPC
http://hjnudt.spaces.live.com/blog/cns!ca093c112896ea44!110.entry 处理驱动程序时IRP它可可以立即完成或中断时,例如,向硬件设备发出请求(通常可以写)I/O port),当设备完成操作时,会触发中断,然后在中断处理函数中得到操作结果。Windows硬件设备的中断和软中断分为几种不同的优先级(IRQL)。主要有两种软中断:DPC(Delayed Procedure Call)和APC(Asynchronous Procedure Call),优先级较低。驱动程序可以中断硬件注册ISR(Interrupt Service Routine),一般是修改IDT条目入口。同样,操作系统也会为DPC和APC注册适当的中断处理程序(也是IDT中)。值得指出的是,DPC它与处理器有关,每个处理器都有一个DPC队列,而APC它与线程有关,每个线程都有它APC队列(实际上包括一个Kernel APC队列和User APC队列,他们的调度策略不同),可想而知,APC这不是严格意义上的中断,因为中断可能发生在任何线程的上下文中,主要称为中断,主要是因为中断IRQL的提升(从PASSIVE到APC),APC一般在线程切换等情况下进行调度。当中断发生时,操作系统将调用中断处理程序,用于硬件设备ISR,一般处理是关闭设备中断,发出一个DPC请求,然后返回。当中断发生时,操作系统将调用中断处理程序,用于硬件设备ISR,一般处理是关闭设备中断,发出一个DPC请求,然后返回。不要在设备中断处理中使用太多CPU时间,主要考虑是否可能失去其他中断。由于硬件设备中断IRQL比DPC高中断,所以在ISR里面DPC直到ISR返回IRQL回到较低较低的水平,才会触发DPC中断,在DPC中断里执行从硬件设备读取数据以及重新请求、开中断等操作。ISR或者DPC可能在任何中断线程上下文(arbitrary thread context)实施,上线程的上下文是看不见的,可以认为是系统借用时间片。 总的来说,Windows的异步I/O在架构中,主要有两种动力,一种是启动要求的线程,一些核心代码将在线程上下文执行,另一种是ISR和DPC,这部分内核代码将在中断中完成,任何线程的上下文都可以使用。回调和事件常用于调度(KEVENT),例如,当向下一层驱动程序发出请求时,可以指定一个完成例程Completion Routine,当下层驱动程序完成此请求时,将调用此例程,通常在此例程中,只是触发一个事件。 另外可以顺便提一下Linux。Linux 2.也有类似的中断机制,它有更多的软中断优先级,即不同的优先级softirq,而类似于DPC,Linux还提供了相应的特殊软中断DPC的就是tasklet。Linux没有一个像windows如此一致的层次驱动程序架构,因此其异步I/O稍微粗糙一点,主要是通过之前的一些阻塞点,现在直接返回-EIOCBRETRY,而让调用者在合适的时机继续重试。在这种方法中,可以认为整个操作是由一个函数完成的。每次操作有进展时,函数都会从头开始执行。当然,已完成的部分将不再实用I/O。最大的好处是原始文件系统和驱动程序不需要完全重写。对于同步调用,只需堵塞即可,因此对系统的修改较小。此时,应提供POSIX aio语义可能需要提供一些用户线程来完成重试过程(回想起来Windows可中断和DPC完成的)。而对于Solaris,如果设备支持异步处理,也是类似的处理方法I/O,可以通过中断完成,否则可以使用内部LWP来模拟。 ISR是中断服务例程。当中断发生时,调用此例程进行处理。一般来说,在中断服务例程中,应关闭中断。因此,处理时间不宜过长。中断服务例程只处理最关键的事情。大部分事情都交给了以后的延迟过程DPC。所以dpc和isr一般不能交换内容。如果需要强制交换,则删除isr中断处理部分,其他可更换。
2.Intel的CPU和AMD的CPU的区别
一:就浮点运算能力而言,INTEL处理器通常只有两个浮点执行单元,AMD处理器一般设计有三个并行浮点执行单元,因此在同级处理器中,AMD处理器的浮点操作能力比INTEL处理器更好。浮点运算能力强,在游戏应用和三维处理应用方面有优势。此外,多媒体指令,INTEL开发了SSE指令集已经发展到现在SSE3了,而AMD还开发了相应的,跟进SSE兼容的增强3D NOW!指令集。相比之下,INTEL的处理器比AMD多媒体指令略胜一筹,很多软件都针对SSE所以在多媒体软件和平面处理软件中进行了优化,与同档次相比AMD处理器,INTEL的CPU更有优势。另外,选择什么样的CPU,价格是一个关键因素。在性能和等级上INTEL处理器整体来说可能比AMD处理器应该有优势,但在价格方面,AMD处理器绝对占主导地位。打个比方:INTEL的P4 2.4B价格在1200左右,性能相似AMD的BARTON 2500 售价只有600左右,想比较一下,AMD的CPU性价比更高。 最终是选择AMD还是INTE的CPU呢?从上面可以知道,AMD的CPU与三维制作、游戏应用、视频处理等相比,INTEL和INTEL的CPU在商业应用、多媒体应用、平面设计等方面具有优势。除了用途,还要综合考虑性价比。这样,我们就可以根据实际用途和资本预算选择最合适的自己CPU。
p> 二:目前INTEL和AMD的CPU的区别之处,以及由于区别之处所带来的性能和效率的差异有以下简要几点,仅供参考: 1。从单晶硅工艺上:INTEL:0。09(降低成本,加大晶体管数量),AMD:0。13(成本比0。09的高),所以导致在都降低相同比例的价格后,INTEL还是挣钱,而AMD最起码不会挣太多的钱啦,搞不好还会陪钱(亏损),虽然市场占有率有所提高,尽而导致最近的AMD诉讼案的发生 2。从流水线上:INTEL:31级(可以提升到更高的主频,但带来更大的发热量:例如P4-670超到7。4G,但得用液氮来散热,而且容易造成指令执行效率低下,所以搞出个超线程来弥补);AMD:20级(指令执行的效率比31级强,但频率提升有限而发热量相对要低,效率和频率是2个不同的发展方向,主要看使用者的选择了) 3。缓存:INTEL:1级16K,2级1M-2M(整数运算以及游戏性能没有AMD的快(还有一个主要原因在起作用,后面再讲),但对于网络和多媒体(浮点运算)的应用比对手强 AMD:1级128K,2级:512K(整数运算快,游戏性能好,但对于多媒体的应用稍微逊色) 4。内存管理架够:INTEL的内存管理架够还是采用传统的由主板上的南北桥方式来管理(造成CPU与内存之间的数据传输延时大,对于游戏执行效果没有AMD的好,但对于日后升级成本有所降低)AMD是CPU内部集成内存控制器(减少了CPU与内存数据传输的延时,(对于游戏性能的提升有相当大的作用,也是前面所说的主要原因,同时也弥补了2级只有512K的所对多媒体应用的不足,但加大了对日后升级的成本的增加:要升级的话您只好把CPU和内存以及主板全都换掉) 5。指令集 INTEL:MMX,SSE,SSE2,SSE3,EM64T (大多数游戏以及软件基于INTEL的指令,对于INTEL有所优化,但64位指令对于现在新的64位系统有兼容性的缺点,所以最近不得不兼容于AMD的X86-64指令,CPU的步进值也从E0变到G1)AMD:3DNOW+,MMX,SSE,SSE2,SSE3,X86-64(在所支持的SSE3中少了2条指令,但问题不大,因为那2条是专门针对INTEL超线程技术的,没有也罢,反正AMD也不支持超线程技术,由于AMD的64位技术源于DEC公司的Alpha技术(64位技术之一),再加上AMD自己的2次开发,所以导致64位技术快速的在民用市场的出现,微软64位系统也不得不基于AMD的X86-64位开发(谁叫AMD先推出民用的64位呢),为了尽快消除对于64位的WINDOWS兼容性的问题,INTEL也被迫开始兼容AMD的64位指令(不是INTEL没有技术开发64位,是由于它的市场策略导致其非常被动,错过了推出64位的最佳时机,让AMD就64位而言站了上风,谁让这2家公司最终还得看微软的脸色呢,从这点上讲,他们还没完全达到市场垄断的地位---硬件厂商还得看软件巨头的脸色,真悲哀!) 综上所诉:现在谁的性价比更高是要看使用者的应用范围(也必然由应用范围来决定),而并不是简单的由价格来决定的,我更不同意所谓的穷人才用AMD的说法(我哥们现在的个人资产有500多万,算是有点钱的吧?!可他装的电脑用的AMD的3000+,为什么呢,因为他不是电脑发烧友,对电脑的知识也不是太懂,他个人认为够用就好,但也得跟的上点潮流,如果他是个发烧友的话去买INTEL的XEON或者AMD的OpteronCPU也很难说的哦,由于INTEL感觉来自AMD的压力所以公司在发展战略上做出了重大的决策的改变(从一味追求频率到追求性能的转变,也不得不放弃由INTEL公司自己创造出来的摩尔定律这个神话,全面转向CPU性能的提升,CPU在3。8G这个频率上画上了个小小的句号,让10G的目标成为了泡影;具可靠的消息:INTEL以后的CPU架够将是基于现在移动CPU的技术上,并且提出了性耗比的概念(而非性价比)并且近期已经成功研发出样品,就性能而言将是现在P4的3倍--5倍,而功耗从笔记本的CPU的5W到台式机CPU的35W到服务器CPU的65W,核心将是双核心或者是4核心,前端总线为:533MHZ,667MHZ,800MHZ,1066MHZ;不再有超线程技术(因为没有必要了,超线程技术的出现主要是来弥补由于流水线过长而导致的效率低下,新的INTEL的CPU不会再用31级流水线,可能只有不到20级或者更底),频率不会超过现有的频率(这意味着3。8G将是INTEL现在乃至以后最高频率)在即将到来的2007年的大较量(INTEL和AMD)中将一决高下,到时候谁胜谁负,谁好谁坏,谁的性价比或者性毫比更高将一目了然,说实话有点为AMD担心(AMD近期曾表示不会对现有的CPU架够改变)但更为咱们中国人自己的龙芯着急!我还是相信那句话:时间会说明一切的!谁将是消费者最应该期待的产品呢?相信在不远的时间里将会出现! 三:对AMD来说,其最受人欢迎的地方,就是它良好的超频性能和低廉的价格,这是它目前占有处理器市场份额的根本原因,也是它的优势。在我们选择时,如果是DIY高手,那选择AMD是肯定没错,能花较少的钱获得更好的性能,价格上同主频的AMD与Intel,前者价格只是后者的一半左右,而且现在AMD的处理器的主板大多数都有傻瓜超频的软件,虽然不能把超频发挥到极限,但也能过一下超频的瘾。而AMD的发热问题一直是大家最关心的问题,其实不然,现在AMD的处理器多加入了过热保护的芯片,所以发热问题已经基本上得到了解决,不必顾虑。 在购买AMD的产品时要注意,由于它良好的超频性能,使一些奸商们开始出售低频版本超频后再打磨的产品,如何识别是不是打磨过的产品,最简单的办法就是看处理器的L2和L3金桥有没有人为切割或焊接的痕迹。如果仍不放心,那么盒装三年质保的AMD产品也是不错的选择。其次就是风扇的选择,AMD处理器超频后的发热问题(注:超频后发热与不超频时发热不同),一直是DIYer们最关心的,所以选择一个好的风扇也是至关重要的。 Intel则向来以稳定著称,对多媒体有较好的指令支持,比较适合一些多媒体爱好者、办公室装机、以及一些不太懂电脑的家庭装机。从超频上来看,由于所有Intel处理器都是锁倍频的,所以在超频上显不出多大优势来,虽然锁了倍频,但也还是能超,只是超频的范围较小,笔者在不改电压的情况下,将一块P4 2.4 BG的超到了3.0G,且在一些3D游戏中如FIFA 2004时能稳定运行,所以Intel的稳定性还是值得我们信耐的。价格上来说,Intel的处理器比起AMD来说可算是高高在上,虽然IT行业里一分钱一分货,但也不乏有一定的垄断因素在里面,但是它优异稳定的性能,使得不少电脑爱好者在装机时,仍然将其设为首选。也正是因为它的稳定,所以许多品牌电脑大多采用了Intel的处理器,可见Intel的稳定性非同一般。这样,在一个不太懂电脑的家庭装机和商用装机机,Intel的处理器有着不可代替的地位。够买Intel的处理器时,由于都锁了倍频,无论是散装还是盒装都可以放心购买,不会出现像AMD那样的打磨产品。但要特别注意的就是在购买盒装产品时,一些奸商往往用散装处理器配上假冒Intel风扇,重新包装后来当盒装产品销售,鉴别的方法单从外观上很难辨别,主要就是看里面的硬塑料包装是否有拆开过的痕迹,再看说明书是印刷品还是复印的,假冒的一般都是复印品。还有就是可以看盒装产品里面赠送的小徽标(就是品牌机外面都贴着印有的Intel Inside的小贴片),真品的小徽标厚而硬,外面有一层较硬的塑料,假货则比较薄,用手指也能把上面的图案刮下来,有的假货甚至没有小徽标。现在散装的Intel处理器与盒装的价格相差不到几十块,而且盒装产品还赠送一个原装风扇,不必在单独购买风扇,所以购买盒装产品是个不错的选择。四:INTEL的赛杨系列属于底端,价格便宜,性价比高,一般游戏或者办公都可以满足,奔腾系列则更加适合应用在专业设计领域,当然各方面都比赛杨高出不少,价格方面由于广告费用,所以只能加在消费者头上了 AMD底端是闪龙,高端是速龙,在游戏方面有出色表现,底端对抗赛杨,高端对抗奔腾,在DIY市场很多消费者都是游戏爱好者,所以占有率也是非常可观的
3. windows下创建进程的步骤 进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。程序只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态实体。而进程则不同,它是程序在某个数据集上的执行,是一个动态实体。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消,反映了一个程序在一定的数据集上运行的全部动态过程。 线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位。线程不能够独立执行,必须依存在进程中,由进程提供多个线程执行控制。从内核角度讲线程是活动体对象,而进程只是一组静态的对象集,进程必须至少拥有一个活动线程才能维持运转。 当某个应用程序调用一个创建进程的函数比如CreateProcess或者用户执行某一个程序(其实windows下用户执行一般普通程序是由explorer.exe调用CreateProcess来完成),操作系统把这个过程分成以下步骤来完成: 1.打开将要在该进程中执行的映像文件。 2.创建Windows执行体进程对象。 3.创建初始线程(栈、堆执行环境初始化及执行线程体对象)。 4.通知Windows子系统新进程创建了(子系统是操作系统的一部分它是一个协助操作系统内核管理用户态/客户方的一个子系统具体的进程为Csrss.exe)。 5.开始执行初始线程(如果创建时候指定了线程的CREATE_SUSPENDED状态则线程暂时挂起不执行)。 6.在新进程和线程环境中完成地址空间的初始化(比如加载必须的DLL和库),然后开始到进程入口执行。 到这里操作系统完成一个新进程的创建过程。下面来看下具体每一步操作系统所做的工作: 1.打开将要在该进程中执行的映像文件。 首先操作系统找到执行的Windows映像然后创建一个内存区对象,以便后面将它映射到新的进程地址空间中。 2.创建Windows执行体进程对象。 接下来操作系统调用内部的系统函数NtCreateProcess来创建一个Windwos执行体进程对象。具体步骤是: (1)建立EPROCESS *分配并初始化EPROCESS结构块 *从父进程处继承得到进程的亲和性掩码 *分配进程的最大最小工作集尺(由两个参数决定PsMinimumWorkingSet PsMaximumWorkingSet) *降新进程的配额块设置为父进程配额块地址,并递增父进程配额块的引用计数 *继承Windows的设备名字空间 *将父进程进程ID保存在新进程对象的InheritedFormUniqueProcessId中 *创建该进程的主访问令牌 *初始化进程句柄表 *将新进程的退出状态设置为STATUS_PENDING (2)创建初始的进程地址空间 *在适当的页表中创建页表项,以映射初始页面 *从MmresidentAvailablePage算出进程工作集大小 *系统空间的非换页部分和系统缓存的页表被映射到进程 (3)初始化内核进程块KPROCESS (4)结束进程地址空间的创建过程 (5)建立PEB (6)完成执行体进程对象的创建过程 3.创建初始线程(栈、堆执行环境初始化及执行线程体对象)。 这时候Windows执行体进程对象已经完全建立完成,但它还没有线程所以无法执行,接下来系统调用NtCreateThread来创建一个挂起的新线程它就是进程的主线程体。 4.通知Windows子系统新进程创建了(子系统是操作系统的一部分它是一个协助操作系统内核管理用户态/客户方的一个子系统具体的进程为Csrss.exe)。接下来操作系统通过客户态(Kernel32.dll)给Windows子系统(Csrss)发送一个新进程线程创建的数据消息,让子系统建立自己的进程线程管理块。当Csrss接收到该消息时候执行下面的处理: *复制一份该进程和线程句柄 *设置进程优先级 *分配Csrss进程块 *把新进程的异常处理端口绑定到Csrss中,这样当该进程发生异常时,Csrss将会接收到异常消息 *分配和初始化Csrss线程块 *把线程插入到进程的线程列表中 *把进程插入到Csrss的线程列表中 *显示进程启动光标 5.开始执行初始线程(如果创建时候指定了线程的CREATE_SUSPENDED状态则线程暂时挂起不执行)。到这里进程环境已经建立完毕进程中开始创建的主线程到这里获得执行权开始执行线程。 6.在新进程和线程环境中完成地址空间的初始化(比如加载必须的DLL和库),然后开始到进程入口执行。 到这步实质是调用ldrInitializeThunk来初始化加载器,堆管理器NLS表TLS数组以及临界区结构,并且加载任何必须要的DLL并且用 DLL_PROCESS_ATTACH功能代码来调用各DLL入口点,最后当加载器初始化例程返回到用户模式APC分发器时进程映像开始在用户模式下执行,然后它调用线程启动函数开始执行。 到这里操作系统完成了所有的创建工作,我们写的程序就这样被操作系统调用运行起来了。
4.http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html
1.
C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 "The C++ Programming Language" 对 volatile 修饰词的说明:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法: 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。例如:
1 |
volatile int i=10; |
2 |
int a = i; |
3 |
... |
4 |
// 其他代码,并未明确告诉编译器,对 i 进行过操作 |
5 |
int b = i; |
volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。注意,在 VC 6 中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无 volatile 关键字,对程序最终代码的影响:
输入下面的代码: