从零开始山寨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:\xxx\bin
确保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
从零开始山寨Caffe·零:必先利其器的更多相关文章
- 从零开始山寨Caffe·陆:IO系统(一)
你说你学过操作系统这门课?写个无Bug的生产者和消费者模型试试! ——你真的学好了操作系统这门课嘛? 在第壹章,展示过这样图: 其中,左半部分构成了新版Caffe最恼人.最庞大的IO系统. 也是历来最 ...
- 从零开始山寨Caffe·伍:Protocol Buffer简易指南
你为Class外访问private对象而苦恼嘛?你为设计序列化格式而头疼嘛? ——欢迎体验Google Protocol Buffer 面向对象之封装性 历史遗留问题 面向对象中最矛盾的一个特性,就是 ...
- 从零开始山寨Caffe·壹:仰望星空与脚踏实地
请以“仰望星空与脚踏实地”作为题目,写一篇不少于800字的文章.除诗歌外,文体不限. ——2010·北京卷 仰望星空 规范性 Caffe诞生于12年末,如果偏要形容一下这个框架,可以用"须敬 ...
- 从零开始山寨Caffe·拾贰:IO系统(四)
消费者 回忆:生产者提供产品的接口 在第捌章,IO系统(二)中,生产者DataReader提供了外部消费接口: class DataReader { public: ......... Blockin ...
- 从零开始山寨Caffe·拾:IO系统(三)
数据变形 IO(二)中,我们已经将原始数据缓冲至Datum,Datum又存入了生产者缓冲区,不过,这离消费,还早得很呢. 在消费(使用)之前,最重要的一步,就是数据变形. ImageNet Image ...
- 从零开始山寨Caffe·玖:BlobFlow
听说Google出了TensorFlow,那么Caffe应该叫什么? ——BlobFlow 神经网络时代的传播数据结构 我的代码 我最早手写神经网络的时候,Flow结构是这样的: struct Dat ...
- 从零开始山寨Caffe·捌:IO系统(二)
生产者 双缓冲组与信号量机制 在第陆章中提到了,如何模拟,以及取代根本不存的Q.full()函数. 其本质是:除了为生产者提供一个成品缓冲队列,还提供一个零件缓冲队列. 当我们从外部给定了固定容量的零 ...
- 从零开始山寨Caffe·柒:KV数据库
你说你会关系数据库?你说你会Hadoop? 忘掉它们吧,我们既不需要网络支持,也不需要复杂关系模式,只要读写够快就行. ——论数据存储的本质 浅析数据库技术 内存数据库——STL的map容器 关 ...
- 从零开始山寨Caffe·贰:主存模型
你左手是内存,右手是显存,内存可以打死显存,显存也可以打死内存. —— 请协调好你的主存 从硬件说起 物理之觞 大部分Caffe源码解读都喜欢跳过这部分,我不知道他们是什么心态,因为这恰恰是最重要的一 ...
随机推荐
- 暴力枚举N级子域名
#!/usr/bin/env python# -*- encoding: utf-8 -*-# A simple and fast sub domains brute tool for pentest ...
- 深入理解javascript原型和闭包(11)——执行上下文栈
继续上文的内容. 执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境.当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境.处于活动状态的执行 ...
- ANT的安装
1.下载ANT http://ant.apache.org/bindownload.cgi 2.将下载下来的压缩包解压到任意文件夹下,例如D盘根目录下D:/apache-ant-1.9.2 3.添加环 ...
- 微信5.4安卓版重回ios风格 导航菜单都放底栏位置
微信5.4安卓版发布更新了,由于本人的手机设置软件自动更新,中午的时候才发现微信换成了5.4版本,启动微信后是一个大大的“转账,就是发消息”,进入微信界面有点小惊喜,导航菜单都改为底部tab方式,顶部 ...
- MySQL关键字
MySQL关键字 ADD ALL ALTER ANALYZE AND AS ASC ASENSITIVE BEFORE BETWEEN BIGINT BINARY BLOB BOTH BY CALL ...
- 【重装系统】线上Linux服务器(2TB)分区参考方案
如果是线上服务器,假设它是 2TB 的 SATA 硬盘.8GB 内存,建议按如下方式进行分区: / 20480M(20G)(主分区) /boot 128M swap 10240M /data 2016 ...
- PHP5不重新编译,如何安装自带的未安装过的扩展,如soap扩展?
在虚拟机的CentOS5.5中,一键安装了PHP运行环境,但发现并没有 soap 扩展,而近期项目用需要用到 webservice. 上述的一键安装(lamp0.4),其实是源码编译安装,PHP配置文 ...
- C/C++ 笔试题
/////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程 ...
- T-SQL 语句的优化
SQL调优. 1.索引是数据库调优的最根本的优化方法.聚簇索引.非聚簇索引. 聚簇索引:物理序与索引顺序相同.(只能有一个) 非聚簇索引:物理顺序与索引顺序不相同. 2.调整WHERE 子句中的连接顺 ...
- 学习 opencv---(1) opencv3.1.0 组件结构浅析
本系列是根据 浅墨大神 的opencv系列而写的,,应该大部分内容会一样..如有侵权还请告知........... 开发环境:win7 + VS2013 + opencv3.1.0 至于OpenCV组 ...