zoukankan      html  css  js  c++  java
  • 从零开始山寨Caffe·零:必先利其器

    工作环境

    巧妇有了米炊

    众所周知,Caffe是在Linux下写的,所以长久以来,大家都认为跑Caffe,先装Linux。

    niuzhiheng大神发起了caffe-windows项目(解决了一些编译、API相异问题)

    以及willyd大神发起的caffe-windows-dependencies项目(整理了依赖库,修正了LMDB在NTFS分区的Bug)

    我们现在可以很欢乐地在Windows上研究Caffe源码,以及山寨它了。

    编辑器

    在Windows下涉及CUDA,Visual Studio必然是首选。如果问原因,这是NVIDIA官方的推荐。

    CUDA最初使用的语言,除了二进制机器码,就是类似CPU汇编的,GPU汇编——PTX代码。

    后来NVIDIA的工程师写了C接口,编译器称为NVCC。

    NVCC相当有趣,它在编译前,需要对CUDA代码以及传统C/C++代码做分离。

    这一步给模板(Template)分离式编程带来比较大的麻烦,C/C++编译器和NVCC编译器不共享某些知识,

    所以你需要重复某些代码。(幸好我们有宏)

    CUDA的地位与DirectX差不多,后者是MS为GPU封装的C++接口。

    CUDA、OpenCL、DirectX旗下的Direct Compute并称为GPGPU通用计算的三个小王子。

    当然,CUDA属于那种为了夺嫡开挂的小人,目前你看到的CUDA框架,只限于NVIDIA GPU,

    因为它在设计的时候,没有从通用GPU出发,直接在自家的硬件物理架构上设计,所以优势很大。

    再说Windows,玩过游戏的人都知道,NVIDIA和MS是多年友商了。

    玩游戏有句信条:千万不要用Linux。这句话可以从两方面解释:

    (I) NVIDIA为Windows全心全意做驱动程序,证据是Linux装显卡驱动曾经

    是一个老大难问题,无数人抱怨,“NVIDIA就是MS的奸细”。

    (II) 很少有开发者用Linux API写游戏(PC端)

    这个现象最近有所改观,基础驱动和CUDA也为部分Linux提供了支持(Ubuntu)。

    就连CES2016上,老黄演示无人驾驶系统Drive PX 2 Demo居然也是跑在Linux(Ubuntu)上。

    似乎还被人看出来跑的是Caffe(疑似),但不论则么说,NVIDIA现在是对Linux有所关注了。

    为了体现与MS的友谊,CUDA几乎是与Visual Studio捆绑的,前提你得先装VS。

    CUDA会把插件和配置直接自动写到VS里去。

    配置NVCC和以及传统C/C++编译器相当繁琐,如果你是民间大神,可以尝试Vim或Sublime。

    但是,最好不要这么作死,VS其实也不是很难用。

    OS及VS

    我个人在Windows10 Threshold 1下工作。

    VS使用是Metro先锋VS2013,相当老掉牙的版本。(VS 2012及以下的UI相当丑,因为同年8月才出了Windows8)。

    VS的默认工作模式是X64 Release。

    依赖环境库

    你的VS工作环境,决定了你的依赖库是如何使用的。

    依赖库有“大三元”的说法:

    如图,就是这三个目录,分别存着:动态库、引用头文件,静态库。

    (I)先说说静态库,VS的静态库是lib文件,GCC的静态库是a文件。

    静态库只能在编译阶段的链接器中使用,这与C/C++的分离式编程有关。

    众所周知,C/C++倡导声明定义分离,这大大加快了整体编译速度,以及方便外部调用。

    于是编译阶段分为两部门:先进行声明的分析,然后再把定义填充进去。

    声明的全部内容通常是提供给外部的,是由零碎的头文件组成,你想用就#include就好了。

    定义的内容,会被链接器灌装起来。根据灌装模式的不同,就出现了静态编译和动态编译两类。

    根据生成内容的不同,又可以分为可执行文件生成和库生成两类。

    利用笛卡尔积,我们大概得到四种模式:

    ★库生成,静态编译( h文件+lib文件(VC) 或者h文件+a文件(GCC) )

    ★库生成,动态编译  (不存在)

    ★可执行文件生成,静态编译 (exe文件)

    ★可执行文件生成,动态编译 ( exe文件+dll or bin文件+so文件(Linux) )

    其中第二种方式是不存在的。所以针对库生成而言,我们只需要h+lib/a文件即可。

    它们应当分别放到include和lib文件夹中。

    在VS中配置头文件/静态库很简单,分为两步:

    ★在工程属性-VC++目录中指定"包含目录"以及”库目录“,分别为h目录以及lib目录

    ★在工程属性-链接器-输入中,手动添加需要的lib文件

    第二步相当重要,如果不做,那么编译是不会错的,但是在链接定义的时候,会找不到lib中的定义:

    error LNK2001: 无法解析的外部符号

    如果你的lib目录没错,那么试着找一找,是不是没有手动添加lib文件(VS不会自动扫描目录文件并且添加)

    (II)再说说动态库,这个方式只有在选择了Release模式编译之后,才会使用。

    先说说Debug和Release的区别。

    Debug版本一般不用来发布,不仅是因为里面包含了Debug代码,而且没有做编译优化,性能有折扣。

    但是有一点好处,就是可以断点、调试,但这非常麻烦。

    由于外部依赖库的灌装,你要Debug你的程序,需要提供pdb符号文件,这意味着你得自己把所有依赖库

    自己编译一遍,得到pdb文件,否则无法Debug,也就无法断点调试。

    因为无法断点,所以Debug只能靠人工推理出断点(推测可能位置,加cout/printf语句测试)

    还有一点,就是Debug版本在调试模式中的执行只需要lib文件,如图:

    但是,一旦你把Debug版本的exe文件拿到别处,就需要dll文件了,这时候需要动态库。

    Release版本则是强制使用动态库,就算是调试模式也无效。

    在VS中配置动态库很简单,只要一步

    ★在工程属性-调试中,指定"环境"的值为:PATH=%PATH%;C:xxxin

    确保bin里存在需要的dll文件,否则OS会一致提示你缺少dll文件。

    另外,Debug和Release版本需要的lib文件和dll文件均是不同的,不能混用。

    一般文件名后补一个"d",表示这是Debug版本的dll/lib。

    教学用·快速依赖环境包

    这个包仅教学使用,阉割庞大的Boost,直接无视了OpenCV(这东西其实没多大用)。

    对于山寨Caffe,足够了。仅仅30MB,适合傻瓜。

    强调,请用于: X64 Release

    度娘:http://pan.baidu.com/s/1NeDrS

    有问题邮箱@我:neopenx@mail.hfut.edu.cn

    2016.2.18 更新lmdb.lib

    -修正Win32平台下,set end of file error!的输出信息问题

    解决方案是在lmdb源码的mdb.c里把这句printf注释掉。

    这是一句毫无意义的输出信息,仅仅在Windows平台下被编译出来,强迫症患者可以选择尝试。

    度娘:http://pan.baidu.com/s/1sk29YlJ

  • 相关阅读:
    Hibernate 中 get()和load()的区别
    Socket网络编程
    经典
    jsp的九大内置对象及EL表达式的隐含对象
    TreeSet
    centos7.4安装npm
    centos7.4中安装docker
    centos7安装nginx
    centos中安装基础环境
    在docker中安装mysql
  • 原文地址:https://www.cnblogs.com/neopenx/p/5187440.html
Copyright © 2011-2022 走看看