Frage

Ich habe den folgenden C-Code:

#include <sys/times.h>
#include <time.h>


float etime_( float *tarray )
{   struct tms buf;

    times( &buf );

    tarray[0] = 1.0 * buf.tms_utime / CLOCKS_PER_SEC;
    tarray[1] = 1.0 * buf.tms_stime / CLOCKS_PER_SEC;

    return tarray[0] + tarray[1];
}

Der Versuch, Port diesen Fortran-Code zu Haskell:

  PROGRAM Test
    IMPLICIT NONE

    REAL t, ta(2), etime

    INTEGER i
    DOUBLE PRECISION x

    do i = 1, 10000
       x = sin( cos( i * 1.0 d0 ) )
       print *, x 
    enddo

    ta(1) = 0.0d0
    ta(2) = 0.0d0

    t = etime( ta )       

    PRINT *, 'user time:    ', ta(1)
    PRINT *, 'system time:  ', ta(2)
    PRINT *, 'process time: ', t

  END

Wie kann ich Array definieren und! oder !!! für den folgenden Code arbeiten?

module Main where

import GHC.Ptr
import GHC.Prim
import System.IO.Unsafe
import Control.Monad

foreign import ccall etime_ :: Ptr Double → IO Double
etime = etime_

main :: IO Int
main = do
  mapM_ (print . sin . cos . (* (1.0 :: Double)) . fromIntegral) [1..10000 :: Int]
  ta ← array 2
  t ← etime ta
  putStrLn $ "user time:    " ++ show (ta !!! 0)
  putStrLn $ "system time:  " ++ show (ta !!! 1)
  putStrLn $ "process time: " ++ show t
  return 0

array :: Int → IO (Ptr a)
array size = undefined

(!) :: Ptr a → Int → IO a
(!) = undefined

(!!!) :: Ptr a → Int → a
(!!!) = undefined
War es hilfreich?

Lösung

Ich schlage vor, diese:

{-# LANGUAGE ForeignFunctionInterface #-}

import Foreign.Marshal.Array (allocaArray, peekArray)
import Foreign.Ptr (Ptr)

foreign import ccall etime_ :: Ptr Float -> IO Float

main :: IO ()
main = do
  mapM_ (print . sin . cos . (* (1.0 :: Double)) . fromIntegral) [1..10000 :: Int]
  allocaArray 2 $ \ta -> do
    ptime <- etime_ ta
    [utime, stime] <- peekArray 2 ta
    putStrLn $ "user time:    " ++ show utime
    putStrLn $ "system time:  " ++ show stime
    putStrLn $ "process time: " ++ show ptime

aber, spezifische Fragen zu beantworten:

array :: Storable a => Int -> IO (Ptr a)
array = mallocArray

(!) :: Storable a => Ptr a -> Int -> IO a
(!) = peekElemOff

(!!!) :: Storable a => Ptr a -> Int -> a
(!!!) ptr = unsafePerformIO . peekElemOff ptr

Ich schlage vor, verwenden Hoogle die Funktionen, die Sie benötigen.

Andere Tipps

Gibt die Summe, Benutzerzeit und Systemzeit als Tupel. Beachten Sie, dass etime einen Zeiger nimmt zu schweben, nicht verdoppeln, so stellen Sie Ihre Arten einig:

{-# LANGUAGE ForeignFunctionInterface #-}

module Main where

import Foreign (Ptr)
import Foreign.Marshal.Array (allocaArray,peekArray)
import Control.Monad (mapM_)

foreign import ccall etime_ :: Ptr Float -> IO Float

etime :: IO (Float, Float, Float)
etime = do
  allocaArray 2 $ \ta -> do
    t <- etime_ ta
    [user,sys] <- peekArray 2 ta
    return (t,user,sys)

main :: IO Int
main = do
  mapM_ (print . sin . cos . (* (1.0 :: Double)) . fromIntegral) [1..10000 :: Int]
  (t,user,sys) <- etime
  putStrLn $ "user time:    " ++ show user
  putStrLn $ "system time:  " ++ show sys
  putStrLn $ "process time: " ++ show t
  return 0

In Anbetracht des folgende zusätzliche Haskell-Modul:

module AllocSymbols (

  (↑≣), -- mallocArray
  (≣⊠), -- free

  (≣→), -- peekElemOff
  (≣←), -- pokeElemOff

  (⥱), -- peekElemOff unsafe

  (⥅), -- advancePtr

) where

import GHC.Ptr
import System.IO.Unsafe
import Foreign.Storable
import Foreign.Marshal.Alloc (free)
import Foreign.Marshal.Array

(↑≣) :: Storable a ⇒ Int → IO (Ptr a)
(↑≣) = mallocArray

(⥱) :: Storable a ⇒ Ptr a → Int → a
a ⥱ i = unsafePerformIO $ peekElemOff a i

(≣→) :: Storable a ⇒ Ptr a → Int → IO a
(≣→) = peekElemOff

(≣←) :: Storable a ⇒ Ptr a → Int → a → IO ()
(≣←) = pokeElemOff

(⥅) :: Storable a ⇒ Ptr a → Int → Ptr a
(⥅) = advancePtr

(≣⊠) :: Ptr a → IO ()
(≣⊠) = Foreign.Marshal.Alloc.free

Und nun können wir Anschluss dieses Stück Fortran-Code:

  PROGRAM Test
    IMPLICIT NONE

    REAL t, ta(2), etime

    INTEGER i
    DOUBLE PRECISION x

    do i = 1, 10000
       x = sin( cos( i * 1.0 d0 ) )
       print *, x 
    enddo

    ta(1) = 0.0d0
    ta(2) = 0.0d0

    t = etime( ta )       

    PRINT *, 'user time:    ', ta(1)
    PRINT *, 'system time:  ', ta(2)
    PRINT *, 'process time: ', t

  END

Wort für Wort zu Haskell:

module Main where

import GHC.Ptr
import AllocSymbols
import Control.Monad

foreign import ccall etime_ :: Ptr Float → IO Float

main :: IO ()
main = do
  mapM_ (print . sin . cos . (* (1.0 :: Double)) . fromIntegral) [1 .. 10000 :: Int]

  ta ← (2 ↑≣) -- ta :: Ptr Float

  (ta ≣← 0) 0.0
  (ta ≣← 1) 0.0

  t ← etime_ ta

  putStrLn $ " user time:    " ++ show (ta ⥱ 0)
  putStrLn $ " system time:  " ++ show (ta ⥱ 1)
  putStrLn $ " process time: " ++ show t

  (ta ≣⊠) -- optional in this case
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top