实习总结报告.docx
《实习总结报告.docx》由会员分享,可在线阅读,更多相关《实习总结报告.docx(19页珍藏版)》请在冰豆网上搜索。
![实习总结报告.docx](https://file1.bdocx.com/fileroot1/2023-1/29/1b4d8ace-e479-46c8-a6bb-9108beebbfaf/1b4d8ace-e479-46c8-a6bb-9108beebbfaf1.gif)
实习总结报告
生产实习报告
实习日程安排
我从2004.8到2004.11在这家公司公司进行实习。
1.刚开始的几个星期,公司经理安排我学习一些有关游戏方面的技术,帮我快速的对游戏行业入门。
2.接下来的时间,经理安排我进行一些实战开发,难度从简单到难。
所进行开发的项目我会在实习收获和体会这段中具体阐述。
实习收获和体会
我在公司主要开发了一个图形转换器,制作一个InstallShiled安装程序和关于3D处理的MMX技术,下面我将介绍我的工作情况和工作收获。
一.图形转换器:
1.设计文档
一:
功能描述:
此软件能将TGA,BMP等图形格式转换为任意制定的格式
功能细化:
1.能显示指定的图片(TGA,RGBA等格式)
2.能显示指定图片的参数(长度,宽度,图片的格式)
3.进行转换的时候能检查该图片长,宽是否为2的幂次,如果不是则发出通知信息
4.具有批处理功能,给定一个文件目录,能将该目录下的所有图片转换为DDS格式
5.转换为DDS时候可以指定MipMap值
二:
模块划分:
UI界面+转换模块
转换模块:
以DLL的形式,针对不同的平台各写一个
其接口为:
boolChangeTo(constchar*SrcName,constchar*DestName,TYPEtype)
enumTYPE
{
BMP=1,
JPEG=2,
DDS=3
};
constchar*SrcName,constchar*DestName应该换成一个结构体
SrcName:
指定的图片名字
DestName:
转换的图片名字
UI界面:
采取多文档视图结构
三:
重要结构
structDDS_PIXELFORMAT
{
DWORDdwSize;
DWORDdwFlags;
DWORDdwFourCC;
DWORDdwRGBBitCount;
DWORDdwRBitMask;
DWORDdwGBitMask;
DWORDdwBBitMask;
DWORDdwABitMask;
};
structDDS_HEADER
{
DWORDdwSize;
DWORDdwHeaderFlags;
DWORDdwHeight;
DWORDdwWidth;
DWORDdwPitchOrLinearSize;
DWORDdwDepth;
DWORDdwMipMapCount;
DWORDdwReserved1[11];
DDS_PIXELFORMATddspf;
DWORDdwSurfaceFlags;
DWORDdwCubemapFlags;
DWORDdwReserved2[3];
};
四:
开发平台
VC6.0+DX9.0
2.接口文档
接口说明
一接口代码:
classIImageChange
{
public:
virtualboolChangeTo(ImageInfo*pImageInfo)=0;
virtualchar*GetDllName()=0;
virtualvoidSetDirectory(constchar*szDirName)=0;
};
上面是一个接口类,这里模仿COM的方法,设计一个抽象类。
任何ImageChangeDLL
必须继承以上接口类。
Example:
classCImageChangeToDDS:
publicIImageChange
{
public:
CImagaChangeToDDS();
~CImageChangeToDDS();
virtualboolChangeTo(ImageInfo*pImageInfo);
virtualchar*GetDllName();
virtualvoidSetDirectory(constchar*szDirName);
};
二接口类成员函数说明:
virtualboolChangeTo(ImageInfo*pImageInfo)=0;
该接口函数传入一个ImageInfo结构的指针(ImageInfo是中间图象数据类型,详见《中间数据结构文档》)。
用户可以在自己类中override该函数,该函数可以按自己意愿任意转换为自己想要的格式。
virtualchar*GetDllName()=0;
该接口函数返回一个代表该该接口的字串,可以说明该接口类的功能和版本。
virtualvoidSetDirectory(constchar*szDirName)=0;
该接口函数设置批处理转换功能时的目的文件夹。
三DLL说明:
DLL一共导出2个函数:
extern"C"
{
IImageChange*CreateInstance();
}
extern"C"
{
voidReleaseInstance(IImageChange*pObj);
}
IImageChange*CreateInstance()产生一个派生自IimageChange的实例,该实例导入到应用程序进程中。
voidReleaseInstance(IImageChange*pObj);释放从CreateInstance()产生的实例资源。
三接口实现
#defineFILENAMELEN128
#definePALNUM256
typedefunsignedcharIMG_BYTE;
typedefunsignedshortIMG_WORD;
typedefunsignedlongIMG_DWORD;
typedeflongIMG_LONG;
typedefboolIMG_BOOL;
typedefDWORDIMG_ARGB;
typedefvoid*IMG_LPVOID;
enumIMAGE_DATA_TYPE
{
//depth32bit
IDT_A8R8G8B8=1,
IDT_X8B8G8R8=2,
//depth24bit
IDT_R8G8B8=3,
//depth16bit
IDT_R5G6B5=4,
IDT_X1R5G5B5=5,
IDT_A4R4G4B4=6,
IDT_X4R4G4B4=7,
//depth8bit
IDT_A1R2G3B2=8,
IDT_R3G3B2=9,
IDT_INDEX8=10,
//depth4bit
IDT_A1R1G1B1=11,
IDT_X1R1G1B1=12,
IDT_INDEX4=13,
//depth1bit
IDT_C1=14,//monochrome0:
BLACK1:
WHITE
IDT_INDEX1=15,
IDT_UNKNOWN=-1,
};
structImageHeader
{
IMG_DWORDdwSize;
IMG_LONGlWidth;
IMG_LONGlHeight;
IMG_BYTEbDepth;//象素的深度
IMG_BYTEbReserve1[3];
IMAGE_DATA_TYPEIDT_TYPE;
IMG_WORDwPlanes;//MustBeZero
IMG_WORDwReserve2;
IMG_DWORDdwReserve;//保留字,可以填充任意数据,如:
指向用户分配的一段内存
IMG_DWORDdwPalClrNum;//调色板的颜色数,如果为-1,则不存在调色板;若为1,4,8,16//代表调色板的颜色总数
IMG_ARGBPalColors[PALNUM];//调色板的数据,dwPalClrNum如果为-1,则该数据无效
};
structImageInfo
{
DWORDdwSize;
LONGlOffset;//该结构与数据的偏移,以BYTE为单位
ImageHeaderiiInfo;
LPVOID*pData;
};
转换模块:
以DLL的形式,针对不同的平台各写一个
其接口为:
boolChangeImage(ImageHeader*pImageHeader)
3.中间数据格式说明
一中间数据格式:
structImageInfo
{
DWORDdwSize;//ImageInfo结构大小
LONGlOffset;//该结构与数据的偏移,以BYTE为单位
TCHARFileName[FILENAMELEN];//源图形文件名
ImageHeaderheader;//图形中间数据的头信息
LONGlDataSize;//图形的数据区大小
LPVOIDpData;//图形的数据区指针
};
structImageHeader
{
DWORDdwSize;//ImageHeader结构大小
LONGlWidth;//位图的宽度,单位:
pixel
LONGlHeight;//位图的高度,单位:
pixel
WORDwDepth;//象素的深度,代表一个象素占多少位
WORDwReserve1;//MustBeZero
IMAGE_DATA_TYPEIDT_TYPE;//位图数据存储类型
WORDwPlanes;//MustBeZero
WORDwReserve2;//MustBeZero
DWORDdwReserve;//保留字,可以填充任意数据,如:
指向用户分配的一段内存
DWORDdwPalClrNum;//调色板的颜色数,如果为0,则不存在调色板;若为1,4,
//代表调色板的颜色总数
ARGBPalColors[PALNUM];//调色板的数据dwPalClrNum如果为0,则该数据无效
};
enumIMAGE_DATA_TYPE
{
//depth32bit
IDT_A8R8G8B8=1,
IDT_X8B8G8R8=2,
//depth24bit
IDT_R8G8B8=3,
//depth16bit
IDT_R5G6B5=4,
IDT_X1R5G5B5=5,
IDT_A1R5G5B5=6,
IDT_A4R4G4B4=7,
IDT_X4R4G4B4=8,
//depth8bit
IDT_R3G3B2=9,
IDT_INDEX8=10,
//depth4bit
//IDT_A1R1G1B1=11,
//IDT_X1R1G1B1=12,
IDT_INDEX4=13,
//depth1bit
IDT_INDEX1=14,
IDT_UNKNOWN=-1,
};
二.使用InstallShield制作安装程序
修改InstallShield对话框的过程:
一:
改变InstallShield自带的对话框的方法
1.首先用VC.NET打开_isres.dll资源DLL,该DLL是InstallShield自带的DLL,里面存放了InstallShield中所有自带对话框模板。
2.在VC.NET中修改对话框(对话框ID可以通过DialogSampler工具得到)
3.保存修改。
注意:
修改InstallShield自带的对话框只能修改一些文本,和一些控件的相对位置,不能修改控件的ID和增加一些控件,不然会导致控件消息映射不正确。
二:
自制可以在InstallShield对话框:
1.首先用VS.NET打开\Examples\CustomDialog\VC++4Project\_isuser.rc,这是一个模板资源,可供用户任意编辑.
2.生成自己的对话框,保存DLL.
3.写对话框处理函数(跟windows下的对话框处理函数类似)
注意:
一定要保存所有的控件ID-Value
InstallShield总结文档:
1.制作自己的对话框作为自己的主界面(修改-isuser.dll,路径为:
C:
\ProgramFiles\InstallShield\Professional-StandardEdition\Redistributable\CompressedFiles\0009-English\Intel32)
2.设置背景图
3.按照InstallShield默认的流程进行安装(也可以按照自己实际需求改动,比如加入自己的对话框)
如果InstallShield提供的对话框不符合用户要求,可以修改_isres.dll,(路径为C:
\ProgramFiles\InstallShield\Professional-StandardEdition\Redistributable\CompressedFiles\0009-English\Intel32)
一些技巧:
1.在修改InstallShield自带的对话框时,我们可以用DialogSampler工具查看所要修改对话框的ID
2.用InstallShield写注册表时,首先必须要调用RegDBSetDefaultRoot来设置rootkey
3.如果要手工控制进度条,可以用SetStatusWindow和StatusUpdate函数来控制
4.InstallShield函数调用顺序:
OnBegin-->OnFirstUIBefore-->OnMainUIBefore-->OnMoving-->OnInstallingFile-->OnUninstallingFile-->OnMoved-->OnFirstUIAfter-->OnMainUIAfter-->OnEnd
5.反安装程序制作:
反安装程序的路径放在注册表中(可在MSDN中搜索Uninstall可以查的该路径),所以只要写一个windows程序去调用这个反安装程序。
三.关于3D处理的MMX技术
具有MMX™技术的处理器的在片高速缓存子系统,是由两个16K的4路线长为32字节的关联高速缓存体构成。
高速缓存具有一个回写机制和一个伪LRU的置换算法。
数据的高速缓存由八个按四字节边界交错的存贮体构成。
在具有MMX™技术的奔腾处理器上,只要引用的数据不在同一个高速缓存体上,就可以被一条读取指令和一条存贮指令同时访问。
在具有MMX™技术的奔腾处理器上,高速缓存访问失败的迟延为8个内部时钟周期。
在具有MMX™技术的动态执行处理器中,最小迟延是10个内部时钟周期。
具有MMX™技术的奔腾处理器和动态执行处理器在分支预测方面,除一个较小的异常处理外(本书2.3.1节中讨论),在功能上完全一样。
分支目标缓冲区(BTB)存贮了预先所见的分支和它们的目标。
当一个分支被预取后,BTB将目标地址直接填入到指令读取单元(IFU)。
一旦分支被执行,BTB将随着目标地址而改变。
使用分支目标缓存时,预先所见的分支被动态预告。
分支目标缓存的预测算法包括了模式匹配和每目标多达4位的预测历史位。
例如,一个具有4个迭代长度的循环将百分之百地被正确预测到。
遵循下列原则将提高预测性能:
编写条件分支(除循环外)可将最常执行的分支紧接在分支指令后(即失败)。
另外,具有MMX™技术的处理器有一个堆栈返回缓存(RSB,ReturnStackBuffer),可以连续地为不同地址上调用的过程正确地预测其返回地址,进一步为展开具有函数调用的循环带来了益处,并删除了某些需要in-line的过程。
另外,在具有MMX™技术的奔腾处理器上,如果两个分支指令的最后一个字节在同一个按四字节对齐的内存段内,则分支不可预测。
如下图所示:
图2-5 相连分支的例子
这种情况,发生在两个相连分支间没有间隔指令且第二个指令只有两个字节长的情况下(如+/-128字节的相对跳转指令)。
为避免这种无法预测的情况,应使第二分支加长,在分支指令中用16位的相对位移代替8位的相对位移。
具有MMX™技术的处理器具有4个写缓存(相对无MMX™技术的奔腾处理器的两个写缓存)。
另外,写缓存可以被U管道使用,也可以被V管道使用(相对无MMX™技术的奔腾处理器的一个写缓存对应一个管道的情况)。
通过对内存写操作进行安排调度,可以提高关键循环的性能。
如果你不想看到写未命中,每组指令不能安排多于4条写指令。
并在安排另外的写指令前调度其它指令。
Intel的MMX™技术是对Intel体系结构(IA)指令集的扩展。
该技术使用了单指令多数据技术(SIMD)技术,以并行方式处理多个数据元素,从而提高了多媒体和通讯软件的运行速度。
MMX™指令集增加了57条新的操作码和一个新的64位四字数据类型。
这种新的64位数据保持了可供MMX™指令操作的成组数据值……
MMX技术在16位高彩和24位真彩数据方面作的并不是最好。
封装好的加,乘逻辑运算符实际上已使得24位成了最具有吸引力的运算方式。
它包含了3个8位(红,绿,兰)元素或?
位固定点(48位是给RGB的)。
完成运算之后(像Gouraud阴影,alpha,等),算法转化成RGB16(555或565)以来更新缓存。
MMX技术并没有内置的算法,也没有为5位而封装的块。
24位的内部运算符使得能提供用8位调色板无法得到的高质量的色彩。
包括:
为雾化,透明化的alpha混合
为橙色火光的RGB(多色彩)的光亮,等等
拟镜的加亮区
瞬间在屏幕上显示多于256种颜色
真正平滑的阴影,随意的混合色彩
少量(或没有)抖动色彩
与其它应用的调色板没有冲突或不协调
与高彩的容量和色彩可媲美,接近于HW加速器
当然,系统的图像存储器的容量决定了是能用16位还是24位彩色。
对于1MB的显卡,只能使用8位的调色板(640*480*2字节需要600KB,如果没有双倍缓冲,或后备缓冲在存储系统中,这只能适应于1MB)。
对于2MB或4MB的显卡,16位就很诱人了。
640*480双倍缓冲后,占用1.2M,仍留下800KB给字符缓存或Z-缓冲。
8位色准许使用一个简单的MOVQ指令来同时以东8个点。
如果有了MMX技术的执行单元和“pairing”指令,它也准许16个点的同时比较或(和)混合。
不幸的是,8位的调色器处理需要在同一时间内从调色板中读出一个字节。
一直以来,老式处理器的8位处理代码在新的CPU上实际上是扮演着“速度绊脚石”的角色来降低性能。
为了奔腾处理器和DynamicExecution(TM)处理的高速度,这应被避免。
例子如下:
自修改代码,它用新的地址或即时值重写了部分指令流。
这使得避免使用其它注册者来得到数据。
在新的CPU中,每个被修改的指令会浪费许多的时钟周期。
因为深层的管道必须被清空,而且缓存必须要重写重取。
随机(不是顺序)进入存储区,作为乘法查找的结果,颜色变幻,阴影化或抖动
经常的数据独立分支,尤其当他们的顺区不规则时
与8位或16位(AL,AH,AX,BL….)一样,32位的注册是很优秀的,将8位像素点的乘法和简单的32位写或0溢出单独字节结合起来
使用MMX指令开发时候需要注意的
∙调整代码,一般情况下不使用向前条件分支,通常使用向后的条件分支。
∙按16字节边界条件对齐频繁执行的分支目标。
∙将循环展开来调度指令。
∙使用软件方式来安排流水线以调度迟延和功能单元。
∙必须成对使用CALL和RET(return)指令。
∙避免使用自修改代码。
∙避免把数据放在代码段。
∙尽可能快地计算出存贮地址。
∙应避免使用包含三个或三个以上微操作代码或指令长度超过7个字节的指令。
如果可能,使用只有一个微操作的指令。
∙不要使用两个8位读取指令来进行16位的读取。
∙在调用被调用保存(callee—save)过程前,先清除部分寄存器的内容。
∙解决阻塞条件,如存贮地址,尽可能地避免可能引起阻塞的读取。
∙一般情况下,一个可以直接由处理器支持的N-字节的数据(8位的字节,16值的字,32位的双字,32位、64位及80位浮点数)应该对齐在下一个最高的2的乘方边界处,避免未对齐的数据。
——按任意边界对齐8位数据。
——在已对齐的4-字节字数据内对齐16位数据。
——以4的任意倍数为边界,对齐32位数据。
——以8的任意倍数为边界,对齐64位数据。
——以128位为边界(即16字节的倍数),对齐80位数据。
合理化建议
我觉得学院开的很多课程的顺序不对,而且有的课程能放在实习结束后再上效果可能会更好,比如:
软件工程,软件测试等,实习前只要将一些基础的课程学好就行了。
附录1:
软件测试
本人目前所在的项目组没有专门的软件测试人员,因此我们充当了双重角色,即是开发人员也是测试人员,本人因此对测试有了更多更深入的了解,在实践方面,除了做最基本的单元测试,功能测试外,还参与了集成测试,系统测试,用户验收测试。
下面先介绍一些软件测试的相关概念和方法,再结合本人的实践谈谈我们是如何做软件测试的,以及心得体会。
软件测试的基本概念和方法
软件测试方法在不同的书籍中可能有不同的分类,不同的叫法和不同的解释。
比如,从测试人员角度看,可分为手动测试和自动测试。
从源代码的角度可分为单元测试和功能测试。
从理论定义来分,可分为黑箱测试,白箱测试和灰箱测试。
而实际项目主要侧重于软件功能的黑箱测试方法:
功能测试(FunctionalityTest),验收测试(AcceptanceTest),用户界面(Userinterface)测试,性能测试(PerformanceTest),压力测试(StressTest)。
下面就简单介绍一下这些测试方法的概念。
白箱测试:
通过程序的源代码进行测试而不使用用户界面。
这种类型的测试需要从代码句法发现内部代码在算法,溢出,路径,条件等等中的缺点或者错误,进而加以修正。
黑箱测试:
通过使用整个软件或某种软件功能来严格地测试,而并没有通过检查程序的源代码或者很清楚地了解该软件或某种软件功能的源代码程序具体是怎样设计的。
测试人员通过输入他们的数据然后看输出的结果从而了解软件怎样工作。
灰箱测试:
就像黑箱测试一样是通过用户界面测试,但是测试人员已经有所了解该软件或某种软件功能的源代码程序具体是怎样设计的。
甚至于还读过部分源代码。
因此测试人员可以有的放矢地进行某种确定的条件/功能的测试。
功能测试:
验证测试软件功能能否正常按照它的设计工作。
看运行软件时的期望行