Голан: Что такое etext?

Я начал профилировать некоторые из моих кодов Go1.2, и верхний элемент всегда имеет что-то под названием 'etext'. Я искал вокруг, но не мог найти много информации об этом, кроме как он мог бы относиться к глубине вызова в процедурах Go. Тем не менее, я не использую никаких подпрограмм Go, и "etext" по-прежнему занимает 75% или более от общего времени выполнения.

(pprof) top20 
Total: 171 samples
    128  74.9%  74.9%      128  74.9% etext

Может кто-нибудь объяснить, что это такое, и есть ли способ уменьшить воздействие?

Ответ 1

Я столкнулся с той же проблемой, после чего нашел это: pprof сломанный в go 1.2?. Чтобы убедиться, что это действительно ошибка 1.2, я написал следующую программу "привет мир":

package main

import (
    "fmt"
    "testing"
)

func BenchmarkPrintln( t *testing.B ){
    TestPrintln( nil )
}

func TestPrintln( t *testing.T ){
    for i := 0; i < 10000; i++ {
            fmt.Println("hello " + " world!")
    }
}

Как вы можете видеть, он вызывает только fmt.Println.

Вы можете скомпилировать это с помощью "go test -c". Запустите с.. /Test.test -test.bench. -test.cpuprofile = test.prof. См. Результат с помощью "go tool pprof test.test test.prof"

(pprof) top10
Total: 36 samples
  18  50.0%  50.0%       18  50.0% syscall.Syscall
   8  22.2%  72.2%        8  22.2% etext
   4  11.1%  83.3%        4  11.1% runtime.usleep
   3   8.3%  91.7%        3   8.3% runtime.futex
   1   2.8%  94.4%        1   2.8% MHeap_AllocLocked
   1   2.8%  97.2%        1   2.8% fmt.(*fmt).padString
   1   2.8% 100.0%        1   2.8% os.epipecheck
   0   0.0% 100.0%        1   2.8% MCentral_Grow
   0   0.0% 100.0%       33  91.7% System
   0   0.0% 100.0%        3   8.3% _/home/xxiao/work/test.BenchmarkPrintln

Вышеприведенный результат получен с использованием go 1.2.1 Затем я сделал то же самое, используя go 1.1.1 и получил следующий результат:

(pprof) top10
Total: 10 samples
   2  20.0%  20.0%        2  20.0% scanblock
   1  10.0%  30.0%        1  10.0% fmt.(*pp).free
   1  10.0%  40.0%        1  10.0% fmt.(*pp).printField
   1  10.0%  50.0%        2  20.0% fmt.newPrinter
   1  10.0%  60.0%        2  20.0% os.(*File).Write
   1  10.0%  70.0%        1  10.0% runtime.MCache_Alloc
   1  10.0%  80.0%        1  10.0% runtime.exitsyscall
   1  10.0%  90.0%        1  10.0% sweepspan
   1  10.0% 100.0%        1  10.0% sync.(*Mutex).Lock
   0   0.0% 100.0%        6  60.0% _/home/xxiao/work/test.BenchmarkPrintln

Вы можете видеть, что результат 1.2.1 не имеет большого смысла. Syscall и etext занимает большую часть времени. Результат 1.1.1 выглядит правильно.

Итак, я убежден, что это действительно ошибка 1.2.1. И я переключился на использование 1.1.1 в своем реальном проекте, и теперь я доволен результатом профилирования.

Ответ 2

Я думаю, что Mathias Urlichs прав относительно отсутствия символов отладки в вашем коде cgo. Стоит отметить, что некоторые стандартные pkgs, такие как net и syscall, используют cgo.

Если вы перейдете к нижней части этого doc в раздел "Предостережения", вы увидите, что третья пуля говорит...

Если программа связана в библиотеке, которая не была скомпилирована с достаточной символической информацией, все образцы, связанные с библиотекой, могут быть списаны на последний символ, найденный в программе перед библиотекой. Это искусственно раздует счетчик для этого символа.

Я не на 100% уверен, это то, что происходит, но я уверен, что именно поэтому etext выглядит настолько занятым (другими словами etext представляет собой набор различных функций, которые не имеют достаточной информации для pprof для анализ должным образом.).