আমি একটি এক্সিকিউটেবল তৈরির আশায় প্যাকেজকম্পিলারটি ব্যবহার করছি যা কেবলমাত্র ইন-টাইম সংকলন ওভারহেডকে সরিয়ে দেয়।
ডকুমেন্টেশনটি ব্যাখ্যা করে যে julia_main
আমার প্রোগ্রামটির যুক্তি কল করার জন্য আমার অবশ্যই একটি ফাংশন সংজ্ঞায়িত করতে হবে এবং একটি "স্নুপ ফাইল" লিখতে হবে, এমন স্ক্রিপ্ট যা আমি পূর্বনির্ধারিত ফাংশনগুলিকে কল করে। আমার julia_main
একক যুক্তি লাগে, বিশ্লেষণের জন্য ইনপুট ডেটাযুক্ত কোনও ফাইলের অবস্থান। সুতরাং জিনিসগুলি সহজ রাখতে আমার স্নুপ ফাইলটি julia_main
নির্দিষ্ট ইনপুট ফাইলটির সাথে কেবল একটি কল করে । সুতরাং আমি আশা করি যে একই ইনপুট ফাইলের বিরুদ্ধে কার্যকর হওয়ার সময় উত্পন্ন এক্সিকিউটেবল রানটি দুর্দান্ত এবং দ্রুত (কোনও সংকলন ওভারহেড) নয়।
কিন্তু হায়, আমি যা দেখছি তা নয়। একটি তাজা জুলিয়া উদাহরণস্বরূপ julia_main
প্রথম মৃত্যুদন্ডের জন্য প্রায় 74 সেকেন্ড এবং পরবর্তী ফাঁসির জন্য প্রায় 4.5 সেকেন্ড সময় লাগে। এক্সিকিউটেবল ফাইলটি যখনই বলা হয় প্রায় 50 সেকেন্ড সময় নেয়।
আমার এই build_executable
ক্রিয়াকলাপটির ব্যবহারটি এরকম দেখাচ্ছে:
julia> using PackageCompiler
julia> build_executable("d:/philip/source/script/julia/jsource/SCRiPTMain.jl",
"testexecutable",
builddir = "d:/temp/builddir4",
snoopfile = "d:/philip/source/script/julia/jsource/snoop.jl",
compile = "all",
verbose = true)
প্রশ্নাবলী:
- উপরোক্ত যুক্তিগুলি কি কোনও জেআইটি ওভারহেড ছাড়াই একটি নির্বাহযোগ্যের আমার লক্ষ্য অর্জনের জন্য সঠিক?
- আমার জন্য অন্য কোন পরামর্শ?
সেই কলটির প্রতিক্রিয়াতে যা ঘটেছিল তা এখানে build_executable
। থেকে লাইন Start of snoop file execution!
থেকে End of snoop file execution!
আমার কোড দ্বারা নির্গত হয়।
Julia program file:
"d:\philip\source\script\julia\jsource\SCRiPTMain.jl"
C program file:
"C:\Users\Philip\.julia\packages\PackageCompiler\CJQcs\examples\program.c"
Build directory:
"d:\temp\builddir4"
Executing snoopfile: "d:\philip\source\script\julia\jsource\snoop.jl"
Start of snoop file execution!
┌ Warning: The 'control file' contains the key 'InterpolateCovariance' with value 'true' but that is not supported. Pass a value of 'false' or omit the key altogether.
└ @ ValidateInputs d:\Philip\Source\script\Julia\JSource\ValidateInputs.jl:685
Time to build model 20.058000087738037
Saving c:/temp/SCRiPT/SCRiPTModel.jls
Results written to c:/temp/SCRiPT/SCRiPTResultsJulia.json
Time to write file: 3620 milliseconds
Time in method runscript: 76899 milliseconds
End of snoop file execution!
[ Info: used 1313 out of 1320 precompile statements
Build static library "testexecutable.a":
atexit_hook_copy = copy(Base.atexit_hooks) # make backup
# clean state so that any package we use can carelessly call atexit
empty!(Base.atexit_hooks)
Base.__init__()
Sys.__init__() #fix https://github.com/JuliaLang/julia/issues/30479
using REPL
Base.REPL_MODULE_REF[] = REPL
Mod = @eval module $(gensym("anon_module")) end
# Include into anonymous module to not polute namespace
Mod.include("d:\\\\temp\\\\builddir4\\\\julia_main.jl")
Base._atexit() # run all exit hooks we registered during precompile
empty!(Base.atexit_hooks) # don't serialize the exit hooks we run + added
# atexit_hook_copy should be empty, but who knows what base will do in the future
append!(Base.atexit_hooks, atexit_hook_copy)
Build shared library "testexecutable.dll":
`'C:\Users\Philip\.julia\packages\WinRPM\Y9QdZ\deps\usr\x86_64-w64-mingw32\sys-root\mingw\bin\gcc.exe' --sysroot 'C:\Users\Philip\.julia\packages\WinRPM\Y9QdZ\deps\usr\x86_64-w64-mingw32\sys-root' -shared '-DJULIAC_PROGRAM_LIBNAME="testexecutable.dll"' -o testexecutable.dll -Wl,--whole-archive testexecutable.a -Wl,--no-whole-archive -std=gnu99 '-IC:\Users\philip\AppData\Local\Julia-1.2.0\include\julia' -DJULIA_ENABLE_THREADING=1 '-LC:\Users\philip\AppData\Local\Julia-1.2.0\bin' -Wl,--stack,8388608 -ljulia -lopenlibm -m64 -Wl,--export-all-symbols`
Build executable "testexecutable.exe":
`'C:\Users\Philip\.julia\packages\WinRPM\Y9QdZ\deps\usr\x86_64-w64-mingw32\sys-root\mingw\bin\gcc.exe' --sysroot 'C:\Users\Philip\.julia\packages\WinRPM\Y9QdZ\deps\usr\x86_64-w64-mingw32\sys-root' '-DJULIAC_PROGRAM_LIBNAME="testexecutable.dll"' -o testexecutable.exe 'C:\Users\Philip\.julia\packages\PackageCompiler\CJQcs\examples\program.c' testexecutable.dll -std=gnu99 '-IC:\Users\philip\AppData\Local\Julia-1.2.0\include\julia' -DJULIA_ENABLE_THREADING=1 '-LC:\Users\philip\AppData\Local\Julia-1.2.0\bin' -Wl,--stack,8388608 -ljulia -lopenlibm -m64`
Copy Julia libraries to build directory:
7z.dll
BugpointPasses.dll
libamd.2.4.6.dll
libamd.2.dll
libamd.dll
libatomic-1.dll
libbtf.1.2.6.dll
libbtf.1.dll
libbtf.dll
libcamd.2.4.6.dll
libcamd.2.dll
libcamd.dll
libccalltest.dll
libccolamd.2.9.6.dll
libccolamd.2.dll
libccolamd.dll
libcholmod.3.0.13.dll
libcholmod.3.dll
libcholmod.dll
libclang.dll
libcolamd.2.9.6.dll
libcolamd.2.dll
libcolamd.dll
libdSFMT.dll
libexpat-1.dll
libgcc_s_seh-1.dll
libgfortran-4.dll
libgit2.dll
libgmp.dll
libjulia.dll
libklu.1.3.8.dll
libklu.1.dll
libklu.dll
libldl.2.2.6.dll
libldl.2.dll
libldl.dll
libllvmcalltest.dll
libmbedcrypto.dll
libmbedtls.dll
libmbedx509.dll
libmpfr.dll
libopenblas64_.dll
libopenlibm.dll
libpcre2-8-0.dll
libpcre2-8.dll
libpcre2-posix-2.dll
libquadmath-0.dll
librbio.2.2.6.dll
librbio.2.dll
librbio.dll
libspqr.2.0.9.dll
libspqr.2.dll
libspqr.dll
libssh2.dll
libssp-0.dll
libstdc++-6.dll
libsuitesparseconfig.5.4.0.dll
libsuitesparseconfig.5.dll
libsuitesparseconfig.dll
libsuitesparse_wrapper.dll
libumfpack.5.7.8.dll
libumfpack.5.dll
libumfpack.dll
libuv-2.dll
libwinpthread-1.dll
LLVM.dll
LLVMHello.dll
zlib1.dll
All done
julia>
সম্পাদনা
আমি ভীত ছিলাম যে একটি ন্যূনতম কাজের উদাহরণ তৈরি করা শক্ত হবে, তবে এটি ছিল সোজা:
TestBuildExecutable.jl
রয়েছে:
module TestBuildExecutable
Base.@ccallable function julia_main(ARGS::Vector{String}=[""])::Cint
@show sum(myarray())
return 0
end
#Function which takes approx 8 seconds to compile. Returns a 500 x 20 array of 1s
function myarray()
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
# PLEASE EDIT TO INSERT THE MISSING 496 LINES, EACH IDENTICAL TO THE LINE ABOVE!
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
end
end #module
SnoopFile.jl
রয়েছে:
module SnoopFile
currentpath = dirname(@__FILE__)
push!(LOAD_PATH, currentpath)
unique!(LOAD_PATH)
using TestBuildExecutable
println("Start of snoop file execution!")
TestBuildExecutable.julia_main()
println("End of snoop file execution!")
end # module
তাজা জুলিয়া উদাহরণস্বরূপ, julia_main
প্রথম নির্বাহের জন্য 8.3 সেকেন্ড এবং দ্বিতীয় মৃত্যুদন্ড কার্যকর করার জন্য আধ মিলি সেকেন্ড সময় নেয়:
julia> @time TestBuildExecutable.julia_main()
sum(myarray()) = 10000
8.355108 seconds (425.36 k allocations: 25.831 MiB, 0.06% gc time)
0
julia> @time TestBuildExecutable.julia_main()
sum(myarray()) = 10000
0.000537 seconds (25 allocations: 82.906 KiB)
0
পরবর্তী আমি কল build_executable
:
julia> using PackageCompiler
julia> build_executable("d:/philip/source/script/julia/jsource/TestBuildExecutable.jl",
"testexecutable",
builddir = "d:/temp/builddir15",
snoopfile = "d:/philip/source/script/julia/jsource/SnoopFile.jl",
verbose = false)
Julia program file:
"d:\philip\source\script\julia\jsource\TestBuildExecutable.jl"
C program file:
"C:\Users\Philip\.julia\packages\PackageCompiler\CJQcs\examples\program.c"
Build directory:
"d:\temp\builddir15"
Start of snoop file execution!
sum(myarray()) = 10000
End of snoop file execution!
[ Info: used 79 out of 79 precompile statements
All done
অবশেষে, একটি উইন্ডোজ কমান্ড প্রম্পটে:
D:\temp\builddir15>testexecutable
sum(myarray()) = 1000
D:\temp\builddir15>
যা চালাতে (আমার স্টপওয়াচ দ্বারা) 8 সেকেন্ড সময় নিয়েছে এবং এটি প্রথমবারের মতো নয়, প্রতিবার কার্যকর হওয়ার সময় এটি চালাতে 8 সেকেন্ড সময় নেয়। এটি প্রতিটি সময় পরিচালিত একটি JIT সংকলন সম্পাদনকারীকে সামঞ্জস্যপূর্ণ, তবে স্নুপ ফাইলটি এড়াতে ডিজাইন করা হয়েছে!
সংস্করণ সংক্রান্ত তথ্য:
julia> versioninfo()
Julia Version 1.2.0
Commit c6da87ff4b (2019-08-20 00:03 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
Environment:
JULIA_NUM_THREADS = 8
JULIA_EDITOR = "C:\Users\Philip\AppData\Local\Programs\Microsoft VS Code\Code.exe"