程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Python >> std::inner

std::inner

編輯:Python

最近團隊產品中用到了一些機器學習方面的算法,涉及到求向量內積,采取的是最樸素的實現方式(元素乘積循環相加)。有一天路上想到 STL 提供了一個模板函數 std::inner_product ,就好奇 libstdc++ 實現上是否對該算法做了什麼優化呢?

於是做了個簡單的實驗:1000 維 double 類型向量乘積,用 std::inner_product 和樸素方法分別計算10000次,g++ -O2優化。第一輪使用原生 double 類型數組,第二輪使用 vector<double> 容器,分別在三個機器環境下進行了計算。
// Processors | physical = 2, cores = 32, virtual = 12, hyperthreading = no
// Speeds | 12x2400.186
// Models | 12xIntel(R) Xeon(R) CPU E5645 @ 2.40GHz
// Caches | 12x256 KB
// GCC | version 3.4.5 20051201 (Red Hat 3.4.5-2)

a*b : std::inner_product(27.934ms), for loop(40.061ms)
a_v*b_v : std::inner_product(27.878ms), for loop(40.04ms)

// Processors | physical = 2, cores = 12, virtual = 12, hyperthreading = no
// Speeds | 12x2100.173
// Models | 12xAMD Opteron(tm) Processor 4170 HE
// Caches | 12x512 KB
// GCC | version 3.4.5 20051201 (Red Hat 3.4.5-2)

a*b : std::inner_product(31.242ms), for loop(47.853ms)
a_v*b_v : std::inner_product(31.301ms), for loop(47.815ms)

// Processors | physical = 1, cores = 0, virtual = 1, hyperthreading = no
// Speeds | 1x2572.652
// Models | 1xIntel(R) Core(TM) i5-3320M CPU @ 2.60GHz
// Caches | 1x6144 KB
// GCC | version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)

a*b : std::inner_product(41.76ms), for loop(33.165ms)
a_v*b_v : std::inner_product(35.913ms), for loop(32.881ms)


可以看出不同環境下 std::inner_product 的表現不盡相同,與樸素的方式相比有優有劣。瞄了一眼 gcc 4.8 的 libstdc++ 的代碼,沒有注意到 std::inner_product 對基本類型做什麼 SSE 指令的優化。不過倒是有個並行計算的版本,可能對超大的向量計算有幫助。

雖然從性能上沒有看到明顯的優勢,但畢竟 std::inner_product 可以簡化一個循環的編碼,至少可以少測一個分支嘛。而且配合重載函數的後兩個 functor 參數,可以做一些有趣的事情,比如算一組數的平方和,比較兩個字符串相同字符的數量等。以後呢可以多嘗試一下用標准庫的算法而不是自己寫循環。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved