Ada,Gnat:受保护类型的效率如何;条目与pthreads进行比较?

Ada,Gnat:受保护类型的效率如何;条目与pthreads进行比较?,ada,Ada,问题是关于在Linux上使用GNAT编译器的受保护类型和条目的性能。互斥仅用作示例(Ada不需要它) 我比较了Rosetta代码中Ada互斥实现的性能 ()使用导入和C接口从Ada调用一个非常简单的C/pthread实现 事实证明,受Ada保护的type+条目的速度慢了36.8倍。 我知道GNAT可能会通过它的运行时库,最终以 调用操作系统原语s.a.pthread。我扣除了一些开销,但没有那么多 问题是:为什么 以防万一-这是我的简单pthread实现: --cmutex.ads 包装CMut

问题是关于在Linux上使用GNAT编译器的受保护类型和条目的性能。互斥仅用作示例(Ada不需要它)

我比较了Rosetta代码中Ada互斥实现的性能 ()使用导入和C接口从Ada调用一个非常简单的C/pthread实现

事实证明,受Ada保护的type+条目的速度慢了36.8倍。 我知道GNAT可能会通过它的运行时库,最终以 调用操作系统原语s.a.pthread。我扣除了一些开销,但没有那么多

问题是:为什么

以防万一-这是我的简单pthread实现:

--cmutex.ads
包装CMutex为
程序锁
Import=>True,
约定=>C,
外部\u名称=>“互斥锁”;
使用解锁程序
Import=>True,
约定=>C,
外部\u名称=>“互斥锁\u解锁”;
结束CMutex;
//C代码
#包括
静态pthread\u mutex\u t mtx=pthread\u mutex\u初始值设定项;
无效互斥锁()
{
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中):

$time./test

 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

分别用于pthread和protected type+条目

请注意,用户时间~=实时,这意味着处理器
忙(它不是空闲的,或以其他方式产生控制)

请在您的问题中包含一个说明您的发现的。假设受保护的条目只是锁定和解锁共享数据是错误的。受保护的条目在条目队列中对任务进行排队和出列,并包含C条件变量的等效项。C互斥体实现不支持线程队列策略,因此不能保证对共享数据的确定性处理。正如@trashgod指出的,最好提供完整的代码、生产工具、版本和参数,这样任何人都可以自己生产这两个程序。@JimRogers我不知道-谢谢!如果我没有弄错的话,排队将防止饥饿,但是为了保证确定性处理,我们需要保证排队顺序。Ada提供了指定排队策略的能力。默认的排队策略是FIFO。所有Ada编译器都需要支持FIFO排队策略和优先级排队策略。以这种方式,处理是确定的。有关详细信息,请参阅。
real    0m20.173s
user    0m20.172s
sys     0m0.000s