Neden C++ dosyasındaki bir işlevin konumu performansını etkiliyor? Aşağıda verilen örnekte, farklı ve tutarlı performans profillerine sahip iki özdeş fonksiyona sahibiz. Bunu araştırmak ve performansın neden bu kadar farklı olduğunu belirlemek nasıl gerçekleşir?Neden C++ dosyasındaki bir işlevin konumu performansını etkiliyor
Örnek, iki fonksiyona sahip olduğumuz için oldukça basittir: a ve b. Her biri sıkı bir döngüde birçok kez çalıştırılır ve optimize edilir (-O3 -march=corei7-avx
) ve zamanlanır.
#include <cstdint>
#include <iostream>
#include <numeric>
#include <boost/timer/timer.hpp>
bool array[] = {true, false, true, false, false, true};
uint32_t __attribute__((noinline)) a() {
asm("");
return std::accumulate(std::begin(array), std::end(array), 0);
}
uint32_t __attribute__((noinline)) b() {
asm("");
return std::accumulate(std::begin(array), std::end(array), 0);
}
const size_t WARM_ITERS = 1ull << 10;
const size_t MAX_ITERS = 1ull << 30;
void test(const char* name, uint32_t (*fn)())
{
std::cout << name << ": ";
for (size_t i = 0; i < WARM_ITERS; i++) {
fn();
asm("");
}
boost::timer::auto_cpu_timer t;
for (size_t i = 0; i < MAX_ITERS; i++) {
fn();
asm("");
}
}
int main(int argc, char **argv)
{
test("a", a);
test("b", b);
return 0;
}
Bazı önemli özellikleri:
- Fonksiyon a ve b aynı İşte kodudur. Aynı birikme işlemini gerçekleştirir ve aynı montaj talimatlarını derler.
- Her test yinelemesinin, zamanlamanın, önbelleklerin ısınmasıyla ilgili sorunları gidermeye ve ortadan kaldırmaya başlamadan önce ısınma süresi vardır. Hareketsiz yavaştır iki testleri ters olursa
[[email protected]:~/code/mystery] make && ./mystery g++-4.8 -c -g -O3 -Wall -Wno-unused-local-typedefs -std=c++11 -march=corei7-avx -I/usr/local/include/boost-1_54/ mystery.cpp -o mystery.o g++-4.8 mystery.o -lboost_system-gcc48-1_54 -lboost_timer-gcc48-1_54 -o mystery a: 7.412747s wall, 7.400000s user + 0.000000s system = 7.400000s CPU (99.8%) b: 5.729706s wall, 5.740000s user + 0.000000s system = 5.740000s CPU (100.2%)
(yani sonra
test(a)
test(b)
arayıp): Bu derlenmiş ve çalışma olduğunda
biz b anlamlı derecede daha yavaştır gösteren şu çıktıyı almak b daha: biz şimdi C++ dosya fonksiyonlarının yerini ters Eğer (a yukarıdaki b tanımını taşımak)
[[email protected]:~/code/mystery] make && ./mystery
g++-4.8 -c -g -O3 -Wall -Wno-unused-local-typedefs -std=c++11 -march=corei7-avx -I/usr/local/include/boost-1_54/ mystery.cpp -o mystery.o
g++-4.8 mystery.o -lboost_system-gcc48-1_54 -lboost_timer-gcc48-1_54 -o mystery
b: 5.733968s wall, 5.730000s user + 0.000000s system = 5.730000s CPU (99.9%)
a: 7.414538s wall, 7.410000s user + 0.000000s system = 7.410000s CPU (99.9%)
sonuç ters ve bir b daha hızlı hale gelir!
[[email protected]:~/code/mystery] make && ./mystery
g++-4.8 -c -g -O3 -Wall -Wno-unused-local-typedefs -std=c++11 -march=corei7-avx -I/usr/local/include/boost-1_54/ mystery.cpp -o mystery.o
g++-4.8 mystery.o -lboost_system-gcc48-1_54 -lboost_timer-gcc48-1_54 -o mystery
a: 5.729604s wall, 5.720000s user + 0.000000s system = 5.720000s CPU (99.8%)
b: 7.411549s wall, 7.420000s user + 0.000000s system = 7.420000s CPU (100.1%)
Temel olarak, C++ dosyasının en üstünde hangi işlev varsa daha yavaştır. sorulara
Bazı cevaplar olabilir:
- derlenmiş kod a ve b her ikisi için aynıdır. Demontaj kontrol edildi. (İlgilenenler için: http://pastebin.com/2QziqRXR)
- Kod, gb 4.8, gcc 4.8.1 ubuntu 13.04, ubuntu 13.10 ve ubuntu 12.04.03 kullanılarak derlenmiştir.
- Intel Sandy Bridge i7-2600 ve Intel Xeon X5482 cpus üzerinde gözlemlenen etkiler.
Bu neden oluyor? Böyle bir şeyi araştırmak için hangi araçlar kullanılabilir?
Farklı sayfalarda sona ermeleri ve bu da fazladan işlere yol açıyor mu? CPU zamanının Kullanıcı değil Sistem ölçümünde tuhaf olduğunu buluyorum. Bu, kullanıcı kodunun zaman almasının değil, aynı zamanda süreçler üzerinde bazı işletim sistemi seviyelerinin çalışması anlamına gelmez. –
Karanlıkta tam bir çekim olarak, b oturumunun ilk kez çalıştırılan bir oturum sonucunda daha da ısınmasını öneririm ... (DÜZENLEME: oh, tersine çevirdiniz ...) –
@DaveS İnanıyorum ki zaman tüm kullanıcı uzayında topraktır. döngü ısınma döngü (ölçüm önce) önbellek ve şube tahmini yeterince ısınma olmalıdır. – Shane