我正在使用ImageMagick(通过PHP imagick扩展)生成一个简单的gif动画,就像这样。
我发现WriteGIFImage()
(https://github.com/ImageMagick/ImageMagick/blob/c807b69de68a33b42fc8725486d5ac81688afd16/coders/gif.c#L1506)函数通过遵循D脚本需要很长时间来写入gif数据。
pid$target::WriteGIFImage:entry
{
self->start_WriteGIFImage = timestamp;
printf(" -> WriteGIFImage\n");
}
pid$target::WriteGIFImage:return
{
this->delta = (timestamp - self->start_WriteGIFImage) / 1000 / 1000;
@deltas["WriteGIFImage"] = sum(this->delta);
printf(" <- WriteGIFImage elapsed %d ms\n", this->delta);
}
// Output
ImagesToBlob
-> WriteImage
-> WriteGIFImage
<- WriteGIFImage elapsed 821 ms
<- WriteImage elapsed 821 ms
ImagesToBlob elapsed 821 ms
Total (ms):
RelinquishMagickMemory 0
WriteBlobByte 0
ImagesToBlob 821
WriteGIFImage 821
WriteImage 821
WriteGIFImage()
是一个很大的功能,我想知道2条语句之间的时间,以便找到最慢的代码块。例如我怀疑此for循环会花费很长时间,因此我需要Dtrace告诉我1673行和1678行之间的时间差。如何使用D脚本来完成它?
1673 for (i=0; i < (ssize_t) image->colors; i++)
1674 {
1675 *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
1676 *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
1677 *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
1678 }
顺便说一句,我发现ScaleQuantumToChar()
和ClampToQuantum()
都是 inline 函数,并且pid*::ScaleQuantumToChar:entry/return
探针无法工作。如何使用D跟踪内联函数?
答案 0 :(得分:2)
除了entry
和return
探针外,pid
提供者还为每个指令偏移量提供探针。如果您执行sudo dtrace -l -n 'pid$target::WriteGIFImage:*' -p <pid>
,它将列出它们。然后,您必须分解代码以确定哪些偏移量对应于代码的哪一行。而且,在构建启用了优化的程序时,这种对应关系可能并不干净。 (相对于代码行,指令可能会乱序。)
您还可以定义自己的用户定义的静态跟踪(USDT)提供程序,并使用它们来检测代码。 dtrace
手册页介绍了操作方法。
尽管如此,但DTrace可能不是最好的工具。使用Instruments的Time Profiler模板,它将告诉您程序在哪里花费时间,一直到代码行(甚至是指令)。