为什么该函数总是返回零运行时间?

Why does the function always return zero elapsed time?

提问人:NEKKITIS 提问时间:11/3/2023 最后编辑:user207421NEKKITIS 更新时间:11/5/2023 访问量:73

问:

我正在使用 Java 编写一个 Android 应用程序。我也在使用 jni 接口调用本机函数。 例如:

JNIEXPORT jint JNICALL Java_com_app_Native_test(JNIEnv *env, jobject object)
{
   steady_clock::time_point begin = steady_clock::now();
   int lenght = 500000000;
   int * arr1 = new int[lenght];
   for(int i = 0; i < lenght; i++)
   {
       *(arr1+i) = i+1;
   }
   matrix<int, 100> matrix1(arr1, lenght);
   steady_clock::time_point end = steady_clock::now();
   return duration_cast<microseconds>(end-begin).count();
}

此函数测量创建数组 (arr1) 和对象 (matrix1) 所需的时间。问题是该函数总是返回 0。事实上,这是不可能的。如果为取决于对象的时间添加一个值,则一切都将按预期工作。那是:

return duration_cast<microseconds>(end-begin).count()+matrix1(1, 1);
//matrix1(1, 1) = 1

在这种情况下,如果我不想不断添加依赖于对象的值,我该怎么办?

C++ 基准测试

评论

0赞 Richard Critten 11/3/2023
int lenght = 5000000000;对于 Android 设备来说,这是一个可怕的数组大小。您的设备有多少内存?
1赞 Andrew Henle 11/3/2023
分辨率是多少?steady_clock
3赞 Alan Birtles 11/3/2023
您是否正在使用编译器优化?您的代码似乎没有任何副作用(请显示一个最小的可重现示例),因此编译器可以将其全部删除,从而导致运行时为零
4赞 Holger 11/3/2023
用于时间测量是高度可疑的。您应该始终使用 .除此之外,如果优化编译器在不使用结果时消除计算也就不足为奇了。intlong
1赞 user207421 11/4/2023
NB 长度,而不是长度。

答:

2赞 Botje 11/5/2023 #1

我采用了您的代码并添加了一个虚拟定义,该定义仅存储提供的指针和总长度:matrix

template <class T, size_t width>
struct matrix {
    matrix(T* ptr, size_t len) : ptr(ptr), len(len) {}
    T* ptr;
    size_t len;
 };

Clang 删除了测量之间的所有代码:(编译器资源管理器链接)

Java_com_app_Native_test():          # @Java_com_app_Native_test()
        push    rbx
        call    std::chrono::_V2::steady_clock::now()@PLT
        mov     rbx, rax
        call    std::chrono::_V2::steady_clock::now()@PLT
// function epilogue follows

如果您实际以某种方式使用该实例,编译器将强制执行完整的初始化过程。这是基准测试中一个非常常见的问题,也是您应该避免自己滚动它的原因。例如,请参阅 Google Benchmark 文档中的“阻止优化”部分。(并在未来切换到基准测试)matrix