[erlang-questions] linked in driver port performance

Sverker Eriksson <>
Thu Jul 15 15:15:30 CEST 2010


Yes, NIFs are "stable enough", with respect to both runtime behavior and 
interface backward compatibility. The plan is to remove the 
"experimental" label from R14B and make no incompatible interface 
changes from R14A.

 > I read in the following link that NIF is good for simple CPU bound
 > operations and linked in port driver is good for IO and fine grained
 > concurrency. Is that not true anymore?

It's basically true except the "fine grained" part. NIFs have no shared 
state by default (like a port) that needs locking. If you choose to 
introduce shared state then you have the freedom (and burden) to 
implement whatever level of locking granularity you want for your data. 

NIFs excel at relatively short synchronous function calls. You can do 
long (CPU or IO bound) calls but then you probably need to do your own 
threading to not block the calling scheduler thread.

There is also a trick to get finer granularity locking for drivers by 
using a pool of ports. Look at the crypto application before R14A when 
it was rewritting using NIFs.

/Sverker, Erlang/OTP


Vinubalaji Gopal wrote:
> great so is NIF stable enough and the recommended solution for any kind of
> interfacing with C/C++?
>
> I read in the following link that NIF is good  for simple CPU bound
> operations and linked in port driver is good for IO  and fine grained
> concurrency. Is that not true anymore?
>
> http://www.erlang-factory.com/upload/presentations/215/ErlangFactorySFBay2010-CliffMoon.pdf
>
> On Wed, Jul 14, 2010 at 3:15 AM, Sverker Eriksson
> <>wrote:
>
>   
>> Actually, NIFs don't use ports so there is no locking at all needed to call
>> a NIF, except
>> the locks already held on the running process. If you introduce data that
>> could be shared
>> between concurrent NIF calls, then you have to serialize that access with
>> your own
>> locking. Using enif_mutex_* for example.
>>
>> You can't use async-threads from a NIF, but you can create custom threads
>> with
>> enif_thread_create and send messages from that thread with enif_send.
>>
>> /Sverker, Erlang/OTP
>>
>>
>> Michael Truog wrote:
>>
>>     
>>> Ok, I didn't realize that you had found the same linked in driver
>>> permanent issue on trapexit.  I at least offered my explanation of what
>>> you seem to be experiencing.
>>>
>>> After looking at NIFs, they actually look like they are using port level
>>> locking by default (as described at
>>> http://erlang.org/doc/man/erl_nif.html by the "Threads and concurrency"
>>> section).  It would be much easier to create a NIF, but there is no
>>> interface for async threads through NIFs (though you can send a process
>>> a message with enif_send, which might help facilitate asynchronous
>>> behavior).  If you stick with a port driver, you would need to use
>>> ERL_DRV_FLAG_USE_PORT_LOCKING as previously mentioned.  Either way you
>>> want the C code to be quick, so you don't block the Erlang VM scheduler
>>> thread.
>>>
>>> - Michael
>>>  On 07/13/2010 10:10 PM, Michael Truog wrote:
>>>
>>>
>>>       
>>>> I think you are having problems with the driver becoming permanent when
>>>> you make the first asynchronous call (there is code that locks the port
>>>> driver so the dll/so can not be unloaded (so it can't be reloaded)). The
>>>> code is trying to protect the code from the possibility that a
>>>> thread finishes but the port driver has already been unloaded, which is
>>>> a valid concern (but could be handled in more complex ways).  The
>>>> problem has been mentioned before here
>>>>
>>>> http://www.trapexit.org/forum/viewtopic.php?t=14295&sid=5de3c47e32136682080511d8d95d458e
>>>> .
>>>>
>>>> ERL_DRV_FLAG_USE_PORT_LOCKING is the flag to make sure different
>>>> scheduler threads can call the port driver instances concurrently (the
>>>> entry in the driver_flags struct member
>>>> http://www.erlang.org/doc/man/driver_entry.html#driver_flags) as
>>>> discussed here http://www.erlang.org/doc/man/erl_driver.html#smp_support
>>>> .  I assume NIFs use the port driver default of "driver level locking"
>>>> (driver_flags == 0, i.e., not ERL_DRV_FLAG_USE_PORT_LOCKING), but I am
>>>> not sure.
>>>>
>>>> - Michael
>>>>
>>>> On 07/13/2010 08:28 PM, Vinubalaji Gopal wrote:
>>>>
>>>>
>>>>         
>>>>> Hi all,
>>>>>  I have been digging hard to write a port linked in driver which would
>>>>> perform better and most of my searches resulted in dead threads (like
>>>>>
>>>>> http://www.trapexit.org/forum/viewtopic.php?t=14295&sid=5de3c47e32136682080511d8d95d458e
>>>>> )
>>>>> and most of my experiments did not give me any good results . I tried to
>>>>> use
>>>>> async threads but I am not able to call these async threads
>>>>> asynchronously.
>>>>> If I try to make multiple erlang processes open the same port it just
>>>>> fails
>>>>> saying that the driver has become permanent. If I try to open a single
>>>>> port
>>>>> driver  - I have to do that in a single gen_server and it blocks when I
>>>>> call  port_command - so all the messages are queued and processed
>>>>> sequentially. Is there a way to write a linked in driver which will
>>>>> perform
>>>>> better and/or better links to help (I have read the erl_driver
>>>>> documentation, erl_ddll documentation numerous times).
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>           
>>>> ________________________________________________________________
>>>> erlang-questions (at) erlang.org mailing list.
>>>> See http://www.erlang.org/faq.html
>>>> To unsubscribe; mailto:
>>>>
>>>>
>>>>
>>>>
>>>>         
>>> ________________________________________________________________
>>> erlang-questions (at) erlang.org mailing list.
>>> See http://www.erlang.org/faq.html
>>> To unsubscribe; mailto:
>>>
>>>
>>>
>>>       
>>     
>
>
>   



More information about the erlang-questions mailing list