ada - Ada, Gnat:与 pthread 相比,受保护类型 + 条目的效率如何?
问题描述
问题是关于在 Linux 上使用 GNAT 编译器的受保护类型和条目的性能。Mutex 仅作为示例使用(Ada 不需要)。
我将来自 Rosetta Code ( https://rosettacode.org/wiki/Mutex#Ada )的 Ada Mutex 实现的性能与使用 import 和 C 接口从 Ada 调用的非常简单的 C/pthread 实现进行了比较。
事实证明,Ada 保护类型 + 条目慢了 36.8 倍。我知道 GNAT 可能会通过它的运行时库并最终调用操作系统原语 sa pthread。我排除了一些开销,但没有那么多。
问题是:为什么?
以防万一 - 这是我的简单 pthread 实现:
-- cmutex.ads
package CMutex is
procedure Lock with
Import => True,
Convention => C,
External_Name => "mutex_lock";
procedure Unlock with
Import => True,
Convention => C,
External_Name => "mutex_unlock";
end CMutex;
// C code
#include <pthread.h>
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
void mutex_lock()
{
pthread_mutex_lock(&mtx);
}
void mutex_unlock()
{
pthread_mutex_unlock(&mtx);
}
==== 编辑 ===
添加最少的可指责代码。它是单线程(仅用于测试),虚拟变量是为了防止优化器优化整个循环。
上面pthread(cmutex)的测试代码是:
with Text_IO; use Text_IO;
with CMutex;
procedure test is
dummy : Integer := 0;
begin
for i in 1 .. 100_000_000 loop
CMutex.Lock;
dummy := dummy + 1;
CMutex.Unlock;
end loop;
Text_IO.Put_Line(Integer'image(dummy));
end test;
保护类型+入口示例的测试代码为:
with Text_IO; use Text_IO;
with Ada_Mutex;
procedure test1 is
dummy : Integer := 0;
mtx : Ada_Mutex.Mutex;
begin
for i in 1 .. 100_000_000 loop
mtx.Seize;
dummy := dummy + 1;
mtx.Release;
end loop;
Text_IO.Put_Line(Integer'image(dummy));
end test1;
其中 Ada_Mutex 是一个包含示例表单 Rosetta 代码的包:
package Ada_Mutex is
protected type Mutex is
entry Seize;
procedure Release;
private
Owned : Boolean := False;
end Mutex;
end Ada_mutex;
--------------------------------
package body Ada_Mutex is
protected body Mutex is
entry Seize when not Owned is
begin
Owned := True;
end Seize;
procedure Release is
begin
Owned := False;
end Release;
end Mutex;
end Ada_Mutex;
使用 pthread 互斥锁的代码的运行时间是(在英特尔 NUC i7 中):
$时间./测试
100000000
real 0m0.557s
user 0m0.553s
sys 0m0.005s
以及使用受保护类型和条目的代码: $ time ./test1
100000000
real 0m19.009s
user 0m19.005s
sys 0m0.005s
没有优化 (-O0) 的时间是:
real 0m0.746s
user 0m0.746s
sys 0m0.000s
和
real 0m20.173s
user 0m20.172s
sys 0m0.000s
分别用于 pthread 和受保护的类型+条目。
注意用户时间~=实时,这意味着处理器很忙(它没有空闲,或者以其他方式让出控制)
解决方案
推荐阅读
- apache-nifi - Apache NiFi - 数据来源
- twitter-bootstrap - 使引导选项卡响应
- swift - 如何扩展表格视图单元格?
- ram - 为什么 mmap 标志会减少单个 Word2Vec 实例的内存消耗
- python - 我编写了一个计算 collatz 猜想的程序,它可以工作但不能计算非常大的数字,我该如何解决这个问题?
- java - Java OPENCV 模板匹配给出了错误的坐标?
- java - 为什么我的预减量没有按预期工作?
- c# - 想在 c# selenium 驱动程序中访问动态 id
- java - Spring Social Facebook - 找不到“Facebook”类型的 bean
- android - WebView 类,文件下载问题