工作環境

巧婦有了米炊

眾所周知,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

有問題郵箱@我:[email protected]

2016.2.18 更新lmdb.lib

-修正Win32平臺下,set end of file error!的輸出資訊問題

解決方案是在lmdb原始碼的mdb.c裡把這句printf註釋掉。

這是一句毫無意義的輸出資訊,僅僅在Windows平臺下被編譯出來,強迫症患者可以選擇嘗試。

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