我今天尝试了linux的perf实用程序,但在解释其结果方面遇到了麻烦.我已经习惯了valgrind的callgrind,这当然是一种完全不同于基于采样的perf方法的方法.
我做了什么:
perf record -g -p $(pidof someapp)
perf report -g -n
Run Code Online (Sandbox Code Playgroud)
现在我看到这样的事情:
+ 16.92% kdevelop libsqlite3.so.0.8.6 [.] 0x3fe57 ? + 10.61% kdevelop libQtGui.so.4.7.3 [.] 0x81e344 ? + 7.09% kdevelop libc-2.14.so [.] 0x85804 ? + 4.96% kdevelop libQtGui.so.4.7.3 [.] 0x265b69 ? + 3.50% kdevelop libQtCore.so.4.7.3 [.] 0x18608d ? + 2.68% kdevelop libc-2.14.so [.] memcpy ? + 1.15% kdevelop [kernel.kallsyms] [k] copy_user_generic_string ? + 0.90% kdevelop libQtGui.so.4.7.3 [.] QTransform::translate(double, double) ? + 0.88% kdevelop libc-2.14.so [.] __libc_malloc ? + …
尝试一些代码并做一些微基准测试我发现float
在包含整数的字符串上使用函数比int
在同一个字符串上使用快2倍.
>>> python -m timeit int('1')
1000000 loops, best of 3: 0.548 usec per loop
>>> python -m timeit float('1')
1000000 loops, best of 3: 0.273 usec per loop
Run Code Online (Sandbox Code Playgroud)
在测试int(float('1'))
哪个运行时比裸机短时,它变得更加奇怪int('1')
.
>>> python -m timeit int(float('1'))
1000000 loops, best of 3: 0.457 usec per loop
Run Code Online (Sandbox Code Playgroud)
我在运行cPython 2.7.6的Windows 7和使用cPython 2.7.6的Linux Mint 16下测试了代码.
我必须补充一点,只有Python 2受到影响,Python 3显示了运行时之间的差异(不显着)差异.
我知道这些微基准测试得到的信息很容易被滥用,但我很好奇为什么函数的运行时存在这样的差异.
我试图找到的实现int
和float
而不同的资料来源,我不能找到它.
为什么memcmp(a, b, size)
比这快得多:
for(i = 0; i < nelements; i++) {
if a[i] != b[i] return 0;
}
return 1;
Run Code Online (Sandbox Code Playgroud)
memcmp是CPU指令还是什么?它必须非常深,因为我memcmp
在循环中使用了大量的加速.
标准C库中的许多函数,尤其是用于字符串操作的函数,最显着的是strcpy(),共享以下原型:
char *the_function (char *destination, ...)
Run Code Online (Sandbox Code Playgroud)
这些函数的返回值实际上与提供的相同destination
.你为什么要浪费多余的回报价值呢?这样的函数无效或返回有用的东西更有意义.
我唯一的猜测是,为什么将函数调用嵌套在另一个表达式中更容易,更方便,例如:
printf("%s\n", strcpy(dst, src));
Run Code Online (Sandbox Code Playgroud)
还有其他合理的理由来证明这个成语吗?
我们有一个简单的内存吞吐量基准.对于大块内存,它所做的只是重复记忆.
在几台不同的机器上查看结果(针对64位编译),Skylake机器的性能明显优于Broadwell-E,保持OS(Win10-64),处理器速度和RAM速度(DDR4-2133)不变.我们不是说几个百分点,而是大约2个因素.Skylake配置为双通道,Broadwell-E的结果不会因双/三/四通道而异.
任何想法为什么会这样?随后的代码在VS2015的Release中编译,并报告完成每个memcpy的平均时间:
64位:Skylake为2.2ms,Broadwell-E为4.5ms
32位:Skylake为2.2ms,Broadwell-E为3.5ms.
通过利用多个线程,我们可以在四通道Broadwell-E构建上获得更大的内存吞吐量,这很不错,但是看到单线程内存访问的这种巨大差异令人沮丧.为什么差异如此显着的任何想法?
我们还使用了各种基准测试软件,他们验证了这个简单示例所展示的内容 - 单线程内存吞吐量在Skylake上更好.
#include <memory>
#include <Windows.h>
#include <iostream>
//Prevent the memcpy from being optimized out of the for loop
_declspec(noinline) void MemoryCopy(void *destinationMemoryBlock, void *sourceMemoryBlock, size_t size)
{
memcpy(destinationMemoryBlock, sourceMemoryBlock, size);
}
int main()
{
const int SIZE_OF_BLOCKS = 25000000;
const int NUMBER_ITERATIONS = 100;
void* sourceMemoryBlock = malloc(SIZE_OF_BLOCKS);
void* destinationMemoryBlock = malloc(SIZE_OF_BLOCKS);
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
while (true)
{
LONGLONG total = 0;
LONGLONG max = 0;
LARGE_INTEGER StartingTime, …
Run Code Online (Sandbox Code Playgroud) performance ×4
c ×2
benchmarking ×1
c++ ×1
function ×1
intel ×1
linux ×1
memcmp ×1
optimization ×1
perf ×1
profiling ×1
python ×1
python-2.7 ×1
strcpy ×1
x86 ×1