জিএইচসিতে অটো-স্পেশালাইজেশনের সক্রিয়তা


392

থেকে ডক্স GHC 7.6 জন্য:

[ওয়াই] আপনার প্রায়শই প্রথমে বিশেষ প্রগমা প্রয়োজন হয় না। মডিউল এম সংকলন করার সময়, জিএইচসি-র অপটিমাইজার (-ओ) স্বয়ংক্রিয়ভাবে এম-তে ঘোষিত প্রতিটি শীর্ষ-স্তরের ওভারলোডেড ফাংশনটি স্বয়ংক্রিয়ভাবে বিবেচনা করে এবং এটি এম-তে যে বিভিন্ন ধরণের বলা হয় তার জন্য বিশেষীকরণ করে The অপটিমাইজার প্রতিটি আমদানি করা INLINABLE ওভারলোডেড ফাংশনও বিবেচনা করে, এবং বিভিন্ন ধরণের জন্য এটি এম তে ডাকা হয় for

এবং

তদুপরি, একটি ফাংশনের জন্য একটি বিশেষ প্রগমা দেওয়া, জিএইচসি স্বয়ংক্রিয়ভাবে যে কোনও টাইপ-শ্রেণীর-ওভারলোডযুক্ত ক্রিয়াকলাপগুলির জন্য বিশেষায়নের তৈরি করবে, যদি তারা স্পেসিয়ালিজ প্রাগমা হিসাবে একই মডিউলে থাকে বা তারা অনন্য; এবং তাই, ট্রানজিটিভ।

সুতরাং জিএইচসির কিছুটা / বেশিরভাগ / সমস্ত (?) ফাংশন স্বয়ংক্রিয়ভাবে প্রগমা INLINABLE ব্যতীত চিহ্নিত করা উচিত এবং যদি আমি স্পষ্টত প্রগমা ব্যবহার করি তবে বিশেষত্বটি ট্রানজিটিভ। আমার প্রশ্ন: অটো- স্পেশালাইজেশন কি ট্রানজিটিভ?

বিশেষত, এখানে একটি ছোট উদাহরণ রয়েছে:

Main.hs:

import Data.Vector.Unboxed as U
import Foo

main =
    let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int)
        (Bar (Qux ans)) = iterate (plus y) y !! 100
    in putStr $ show $ foldl1' (*) ans

Foo.hs:

module Foo (Qux(..), Foo(..), plus) where

import Data.Vector.Unboxed as U

newtype Qux r = Qux (Vector r)
-- GHC inlines `plus` if I remove the bangs or the Baz constructor
data Foo t = Bar !t
           | Baz !t

instance (Num r, Unbox r) => Num (Qux r) where
    {-# INLINABLE (+) #-}
    (Qux x) + (Qux y) = Qux $ U.zipWith (+) x y

{-# INLINABLE plus #-}
plus :: (Num t) => (Foo t) -> (Foo t) -> (Foo t)
plus (Bar v1) (Bar v2) = Bar $ v1 + v2

জিএইচসি কলটিতে বিশেষীকরণ করেছে plus, তবে সেই কর্মক্ষমতাটি হ্রাস করে এমন ক্ষেত্রে বিশেষীকরণ করে না(+)Qux Num

তবে, একটি সুস্পষ্ট প্রগমা

{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}

দস্তাবেজগুলি যেমন নির্দেশ করে তেমনি ট্রানজিটিভ স্পেশালাইজেশনে ফলাফল , তাই (+)বিশেষীকরণ করা হয় এবং কোডটি 30x দ্রুত (উভয়ই সংকলিত -O2) হয়। এই প্রত্যাশিত আচরণ? আমার কি কেবল (+)স্পষ্টত প্রগমা দিয়ে ট্রানজিটিভ বিশেষায়িত হওয়ার আশা করা উচিত?


হালনাগাদ

7.8.2 এর জন্য দস্তাবেজগুলি পরিবর্তন হয়নি, এবং আচরণও একই, তাই এই প্রশ্নটি এখনও প্রাসঙ্গিক।


33
উত্তরটি আমি জানি না তবে এটির সাথে সম্পর্কিত হতে পারে বলে মনে হচ্ছে: ghc.haskell.org/trac/ghc/ticket/5928 সম্ভবত একটি নতুন টিকিট খোলার বা সেখানে আপনার তথ্য যুক্ত করার পক্ষে যদি আপনি মনে করেন এটি সম্ভবত 5928 এর সাথে সম্পর্কিত
jberryman

6
@jberryman আছে যে টিকেট এবং আমার প্রশ্নের মধ্যে দুটি পার্থক্য হবে বলে মনে হচ্ছে: 1) টিকেট-এর, সমতুল্য plusছিল না INLINABLE এবং 2 হিসাবে চিহ্নিত) simonpj নির্দেশিত কিছু টিকেট কোড দিয়ে যাচ্ছে ইনলাইনিং ছিল, কিন্তু থেকে কোর আমার উদাহরণটি দেখায় যে কোনও ফাংশনই ইনলাইনড ছিল না (বিশেষত, আমি দ্বিতীয় Fooনির্মাণকারী থেকে মুক্তি পেতে পারি না , অন্যথায় জিএইচসি ইনলাইনড স্টাফ)।
ক্রোকিয়া

5
আহ ঠিক আছে. আপনি যখন সংজ্ঞা দেন তখন কী হয় plus (Bar v1) = \(Bar v2)-> Bar $ v1 + v2, যাতে এলএইচএস কল-সাইটে পুরোপুরি প্রয়োগ হয়? এটি কি অন্তর্ভুক্ত হয় এবং তারপরে স্পেশালাইজেশন লাথি দেয়?
jberryman

3
@ জবেরিম্যান ফানি আপনি জিজ্ঞাসা করা উচিত। আমি এই প্রশ্নটি নিয়ে এই রাস্তায় নেমেছি যা এই ট্র্যাকের প্রতিবেদনের দিকে পরিচালিত করে । plusএই লিঙ্কগুলির কারণে আমার কাছে প্রথমে বিশেষভাবে পুরোপুরি প্রয়োগ করার জন্য কল ছিল , কিন্তু বাস্তবে আমি কম বিশেষীকরণ পেয়েছি: কলটিও বিশেষায়িত plusছিল না। এর জন্য আমার কোনও ব্যাখ্যা নেই, তবে অন্য একটি প্রশ্নের জন্য এটি ছেড়ে দেওয়ার ইচ্ছা ছিল বা আশা করি যে এটির উত্তর দিয়ে সমাধান হয়ে যাবে।
crockeea

11
Ghc.haskell.org/trac/ghc/wiki/ReportABug থেকে : "যদি সন্দেহ হয় তবে কেবল আপনার বাগটি রিপোর্ট করুন।" আপনার খারাপ লাগা উচিত নয়, বিশেষত যেহেতু এখানে পর্যাপ্ত পরিমাণ অভিজ্ঞ অভিজ্ঞ হেস্কেলার আপনার প্রশ্নের উত্তর কীভাবে জানেন না। এর মতো পরীক্ষার কেসগুলি সম্ভবত জিএইচসি দেবদের পক্ষে সত্যই মূল্যবান। যাই হোক শুভকামনা! আপনি টিকিট দাখিল করা প্রশ্নটি আপডেট করেছেন
jbertman

উত্তর:


4

ছোট উত্তর:

প্রশ্নের মুখ্য বিষয়গুলি, যেমন আমি তাদের বুঝতে পারি, নীচে:

  • "অটো-বিশেষায়নের স্থানান্তর কী?"
  • আমার কি কেবল প্রত্যাশা করা উচিত (+) একটি স্পষ্টত প্রগমা দিয়ে ট্রানজিটিভ বিশেষায়িত হবে?
  • (স্পষ্টতই উদ্দেশ্যে) এটি কি জিএইচসি-র বাগ? এটি কি ডকুমেন্টেশনের সাথে বেমানান?

আফাইক, উত্তরগুলি হ'ল না, বেশিরভাগ হ্যাঁ তবে এর অন্য উপায় রয়েছে এবং না No.

কোড ইনলাইনিং এবং টাইপ অ্যাপ্লিকেশন বিশেষীকরণ হ'ল গতি (সম্পাদনের সময়) এবং কোড আকারের মধ্যে একটি বাণিজ্য। ডিফল্ট স্তরটি কোডটি ফোটানো ছাড়াই কিছু গতি অর্জন করে। আরও বিস্তৃত স্তর নির্বাচন করা SPECIALISEপ্রগমার মাধ্যমে প্রোগ্রামারের বিবেচনার বাকী।

ব্যাখ্যা:

অপটিমাইজার প্রতিটি আমদানি করা INLINABLE ওভারলোডেড ফাংশনও বিবেচনা করে এবং এটি এম-তে যে বিভিন্ন ধরণের বলা হয় তার জন্য এটি বিশেষজ্ঞ করে special

ধরুন fএকটি ফাংশন যার টাইপ একটি টাইপ পরিবর্তনশীল রয়েছে aএকটি টাইপ বর্গ দ্বারা সীমাবদ্ধ C a। জিএইচসি ডিফল্টরূপে fকোনও প্রকারের অ্যাপ্লিকেশন (পরিবর্তনের aজন্য t) fএকই ধরণের অ্যাপ্লিকেশনটির সাথে যদি বলা হয় (ক) একই মডিউলের কোনও ফাংশন, বা (খ) fচিহ্নিত করা হয় INLINABLE, তবে অন্য যে কোনও মডিউল আমদানি করে f থেকে B। সুতরাং, স্বয়ং-বিশেষজ্ঞতা সকর্মক নয়, এটা শুধুমাত্র স্পর্শ INLINABLEআমদানি ও আহ্বান ফাংশন সোর্স কোডে এর A

আপনার উদাহরণে, আপনি যদি উদাহরণটি পুনরায় লিখেন Num:

instance (Num r, Unbox r) => Num (Qux r) where
    (+) = quxAdd

quxAdd (Qux x) (Qux y) = Qux $ U.zipWith (+) x y
  • quxAddদ্বারা বিশেষভাবে আমদানি করা হয় না MainMainউদাহরণস্বরূপ অভিধানটি আমদানি করে Num (Qux Int)এবং এই অভিধানটি quxAddরেকর্ডটিতে অন্তর্ভুক্ত করে (+)। তবে অভিধানটি আমদানি করা হলেও অভিধানে ব্যবহৃত সামগ্রীগুলি নয় not
  • plusকল করে না quxAdd, এটি (+)উদাহরণস্বরূপ অভিধানে রেকর্ডের জন্য সঞ্চিত ফাংশনটি ব্যবহার করে Num t। এই Mainঅভিধানটি কম্পাইলার দ্বারা কল সাইটে (ইন ) সেট করা আছে ।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.