জাভাস্ক্রিপ্ট ভাষা ব্যবহার করে এফএমজেডে কৌশলগুলি বিকাশ করার সময়, যেহেতু কৌশল স্থাপত্যটি জরিপ করা হয়।exchange.Go
ফাংশনটি কিছু ইন্টারফেসে সমান্তরাল কল করতে ব্যবহৃত হয়, যাতে কিছু সমান্তরাল দৃশ্যের প্রয়োজনীয়তা পূরণ করা যায়। তবে আপনি যদি একাধিক ক্রিয়াকলাপ সম্পাদন করতে একটি একক থ্রেড তৈরি করতে চান তবে এটি অসম্ভব। উদাহরণস্বরূপ পাইথন ভাষার মতো,threading
লাইব্রেরী কিছু সমান্তরাল নকশা করতে.
এই প্রয়োজনীয়তার ভিত্তিতে, এফএমজেড প্ল্যাটফর্মটি সিস্টেমের নীচের স্তরটি আপগ্রেড করেছে। জাভাস্ক্রিপ্ট ভাষায় সত্যিকারের মাল্টিথ্রেডিং সমর্থনও যুক্ত করা হয়েছে। বিস্তারিত বৈশিষ্ট্যগুলির মধ্যে রয়েছেঃ
পরবর্তী, আমি আপনাকে প্রতিটি ফাংশন একের পর এক বুঝতে সাহায্য করব।
দ্য__Thread
ফাংশন একটি থ্রেড তৈরি করতে পারেন এবং একই সময়ে একটি ফাংশন চালানো. উদাহরণস্বরূপ, আপনি একটি সমান্তরাল ফাংশন তৈরি করতে হবেfunc1
, কি করেfunc1
আমরা এটিকে 0 থেকে 9 পর্যন্ত জমা হতে দিতে পারি। ধীরে ধীরে জমা হওয়ার প্রক্রিয়াটি দেখার জন্য, আমরা ফাংশন 1 এর ফর লুপটি ব্যবহার করি যাতে প্রতিটি সময় বিরতি দেওয়া হয় (স্লিপ ফাংশনটি নির্দিষ্ট সংখ্যক মিলিসেকেন্ডের জন্য ঘুমাতে ব্যবহৃত হয়) নির্দিষ্ট সময়ের জন্য।
function func1(sleepMilliseconds) {
var sum = 0
for (var i = 0 ; i < 10 ; i++) {
sum += i
Sleep(sleepMilliseconds)
Log("sum:", sum)
}
return sum
}
function main() {
// Use the __Thread function to create a thread concurrently, and the parameter 200 is the parameter of the func1 function,
// If the func1 function has multiple parameters, here we pass the corresponding parameters.
var thread1Id = __Thread(func1, 200)
// Here we need to wait for the execution result of the thread whose thread Id is thread1Id, otherwise all threads will be released directly after the main function is executed.
var ret = __threadJoin(thread1Id)
Log("ret:", ret)
}
ব্যবহারিক প্রয়োগে, আমরা একই সাথে http অনুরোধ করতে পারি এইভাবেঃ
function main() {
let threads = [
"https://www.baidu.com",
"https://www.163.com"
].map(function(url) {
return __Thread(function(url) {
Log("GET", url)
return HttpQuery(url)
}, url)
})
threads.forEach(function(tid) {
Log(__threadJoin(tid))
})
}
উপরের উদাহরণে, আমরা__threadJoin
মূল ফাংশনে ফাংশন অবশেষে সমান্তরাল থ্রেড শেষ করার জন্য অপেক্ষা করুন।ret
রিটার্ন মান পায়__threadJoin
ফাংশন, এবং আমরা রিটার্ন মান মুদ্রণ, আমরা সমান্তরাল থ্রেড এক্সিকিউশন নির্দিষ্ট ফলাফল পর্যবেক্ষণ করতে পারেন.
// id: thread ID, terminated: whether it was forced to stop, elapsed: time-consuming (nanoseconds), ret: the return value of the thread execution function
ret: {"id":1,"terminated":false,"elapsed":2004884301,"ret":45}
function func1(sleepMilliseconds) {
var sum = 0
for (var i = 0 ; i < 10 ; i++) {
sum += i
Sleep(sleepMilliseconds)
Log("sum:", sum)
}
return sum
}
function main() {
var thread1Id = __Thread(func1, 200)
Sleep(1000)
retThreadTerminate = __threadTerminate(thread1Id)
Log(retThreadTerminate) // true
}
আমরা এখনও এই উদাহরণটি ব্যবহার করছি, একটি থ্রেড তৈরি করার পরে, আপনি 1 সেকেন্ড অপেক্ষা করার পর জোর করে থ্রেডের কার্যকরকরণ বন্ধ করতে পারেন।
ইন্টার-থ্রেড যোগাযোগ প্রধানত ব্যবহার করে__threadPostMessage
ফাংশন এবং__threadPeekMessage
আসুন নিচের সহজ উদাহরণটি দেখিঃ
function func1() {
var id = __threadId()
while (true) {
var postMsg = "Message from thread function func1" with "from id:" + id +
__threadPostMessage(0, postMsg) // Send a message to the main thread
var peekMsg = __threadPeekMessage(0) // Receive messages from the main thread
Log(peekMsg)
Sleep(5000)
}
}
function main() {
var threadId = __Thread(func1)
while (true) {
var postMsg = "Messages from the main function of the main thread"
__threadPostMessage(threadId, postMsg)
var peekMsg = __threadPeekMessage(threadId)
Log(peekMsg, "#FF0000") // #FF0000 , Set the log to red for distinction
Sleep(5000)
}
}
দ্য__threadPostMessage
function একটি থ্রেডে একটি বার্তা পাঠাতে ব্যবহৃত হয়। প্রথম প্যারামিটারটি নির্দিষ্ট থ্রেডের আইডি যা পাঠানো হবে এবং দ্বিতীয় প্যারামিটারটি বার্তা পাঠানো হবে, যা একটি স্ট্রিং, একটি মান, একটি অ্যারে, বা একটি JSON অবজেক্ট এবং তাই হতে পারে। বার্তাগুলি সমান্তরাল থ্রেড ফাংশনে মূল থ্রেডে পাঠানো যেতে পারে এবং প্রধান থ্রেডের আইডি 0 হিসাবে সংজ্ঞায়িত করা হয়।
দ্য__threadPeekMessage
ফাংশন একটি নির্দিষ্ট থ্রেড দ্বারা প্রেরিত বার্তা নিরীক্ষণ করতে ব্যবহৃত হয়। প্রথম প্যারামিটারটি থ্রেডের নির্দিষ্ট আইডি নিরীক্ষণ করা। দ্বিতীয় প্যারামিটারটি টাইমআউট সময় (মিলিসেকেন্ডে) সেট করতে পারে, অথবা এটি -1 এ সেট করা যেতে পারে, যার অর্থ ব্লকিং, এবং এটি একটি বার্তা না হওয়া পর্যন্ত ফিরে আসবে না। আমরা সমান্তরাল থ্রেড ফাংশনে বর্তমান থ্রেডে প্রধান থ্রেড দ্বারা প্রেরিত বার্তাটি শুনতে পারি এবং প্রধান থ্রেডের আইডি 0 হিসাবে সংজ্ঞায়িত করা হয়।
অবশ্যই, প্রধান থ্রেডের সাথে যোগাযোগকারী সমান্তরাল থ্রেড ব্যতীত। সমান্তরাল থ্রেডগুলিও একে অপরের সাথে সরাসরি যোগাযোগ করতে পারে।
উপরের উদাহরণে,var id = __threadId()
ব্যবহার করা হয়, এবং__threadId()
ফাংশন বর্তমান থ্রেডের আইডি পেতে পারে।
থ্রেডগুলির মধ্যে যোগাযোগের পাশাপাশি, ভাগ করা ভেরিয়েবলগুলি ইন্টারঅ্যাকশনের জন্যও ব্যবহার করা যেতে পারে।
function testFunc() {
__threadSetData(0, "testFunc", 100) // Stored in the current thread environment, key-value pair testFunc : 100
Log("testFunc execution completed")
}
function main() {
// threadId is 1, the created thread with threadId 1 will be executed first, as long as the thread resources are not reclaimed, the variables stored locally in the thread will be valid
var testThread = __Thread(testFunc)
Sleep(1000)
// export in main, get testFunc: 100
Log("in main, get testFunc:", __threadGetData(testThread, "testFunc")) // Take out the value whose key name is testFunc
}
উপরের সব ফাংশন একটি সহজ বিক্ষোভ. আসুন একটু জটিল পরীক্ষা উদাহরণ তাকান.
এই পরীক্ষার কৌশল ঠিকানাঃhttps://www.fmz.com/strategy/401463
এক নজরে, আপনি হয়তো জানেন না যে এই পরীক্ষার কৌশলটি কী করে। এটি কোন ব্যাপার না, আসুন এটি ব্যাখ্যা করি। প্রথমে, আসুন জেনে নেওয়া যাক WASM কি?
WebAssembly
হয়WASM
, WebAssembly
এটি একটি নতুন এনকোডিং ফরম্যাট এবং ব্রাউজারে চালানো যেতে পারে,WASM
ব্যবহার করা যেতে পারেJavaScript
এবং WASM কম স্তরের অ্যাসেম্বলার ভাষার মত।
তারপরে পরীক্ষার কৌশলটি হ'ল ওয়াসম এবং জাভাস্ক্রিপ্টের কার্যকারিতা তুলনা করা, তবে তুলনা করার সময়, দুটি কার্যকরকরণ পদ্ধতি ধারাবাহিকভাবে কার্যকর করা যেতে পারে, এবং প্রতিটিটির সময় সাপেক্ষে গণনা করা হয়। দুটি কার্যকরকরণ পদ্ধতির সমান্তরালভাবে কার্যকর করার অনুমতি দেওয়াও সম্ভব, এবং পরিসংখ্যানগুলি সময় সাপেক্ষে। এখন যেহেতু জাভাস্ক্রিপ্ট ভাষার কৌশলটির অন্তর্নিহিত সমান্তরাল বাস্তবায়ন সমর্থিত হয়েছে, পরীক্ষার কৌশলটি স্বাভাবিকভাবে তুলনা করতে এবং একই অ্যালগরিদমের কার্যকরকরণের গতি তুলনা করতে সমান্তরাল পদ্ধতি ব্যবহার করে।
// Recursive algorithm of Fibonacci Numbers in C Language
int fib(int f) {
if (f < 2) return f;
return fib(f - 1) + fib(f - 2);
}
// A recursive algorithm for the same Fibonacci numbers, written in JavaScript
function fib(f) {
if (f < 2) return f
return fib(f - 1) + fib(f - 2)
}
এটি দেখা যায় যে দুটি ফাইব ফাংশন অ্যালগরিদমের যুক্তি ঠিক একই। নিম্নলিখিত পরীক্ষার কৌশলটির উত্স কোডঃ
function main() {
// In order to make it easier to see the code, I write the comment on the following code directly:
let cycle = 100 // The test executes the loop 100 times
let input = 30 // The parameters that will be passed to the algorithm fib function
let threads = [
__Thread(function(cycle, input) { // A thread is created concurrently to perform calculations using the JavaScript version of the fib function
function fib(f) { // The specific algorithm used for testing, the fib function
if (f < 2) return f
return fib(f - 1) + fib(f - 2)
}
let ret = 0
for (let i = 0; i < cycle; i++) { // loop for 100 times
ret = fib(input); // Call the fib function of the JavaScript language
Log("javascript progress: ", i)
}
return 'javascript fib: ' + ret
}, cycle, input),
__Thread(function(cycle, input) { // Run a thread concurrently to perform calculations using the wasm version of the fib function
let data = 'data:hex,0061736d010000000186808080000160017f017f0382808080000100048480808000017000000583808080000100010681808080000007908080800002066d656d6f727902000366696200000aa480808000019e80808000000240200041024e0d0020000f0b2000417f6a10002000417e6a10006a0b'
let m = wasm.parseModule(data) // The data variable is the hex string of the wasm-encoded C language fib function, and the wasm model m is created using wasm.parseModule
let instance = wasm.buildInstance(m, { // Model instantiation, allocate a certain stack space
stack_size: 65 * 1024 * 1024,
})
let ret = 0
for (let i = 0; i < cycle; i++) { // loop for 100 times
ret = instance.callFunction('fib', input) // Calling the fib function code in the wasm instance is equivalent to calling the int fib(int f) function
Log("wasm progress: ", i)
}
return 'wasm fib: ' + ret
}, cycle, input)
]
// The elements in the threads array are the IDs returned by the __Thread function
threads.forEach(function(tid) {
let info = __threadJoin(tid) // Use the __threadJoin function to wait for two concurrent threads to execute and get the execution result
Log('#'+tid, info.ret, 'elapsed:', info.elapsed / 1e6, "#ff0000") // output execution result
})
}
সহজভাবে বলতে গেলে, WASM একটি প্রোগ্রাম কোড যা উচ্চতর কার্যকারিতা সম্পন্ন করে। উদাহরণে, আমরা
আমরা ওয়েবসাইট ব্যবহার করে রূপান্তর করতে পারিঃhttps://wasdk.github.io/WasmFiddle/
// Recursive Algorithm of Fibonacci numbers in C Language
int fib(int f) {
if (f < 2) return f;
return fib(f - 1) + fib(f - 2);
}
নিম্নলিখিত কমান্ড ব্যবহার করা যেতে পারেঃ
python -c "print('data:hex,'+bytes.hex(open('program.wasm','rb').read()))"
এনকোড করা হেক্স স্ট্রিং হলlet data = 'data:hex,0061736d0100000001868...
কোডের মধ্যে।
তারপর ফাংশনের মাধ্যমে এটিকে একটি ওয়াসম মডেলের মধ্যে বিশ্লেষণ করুনwasm.parseModule()
এফএমজেড দ্বারা সমন্বিত।
ফাংশনের মাধ্যমে wasm মডেল ইনস্ট্যান্স তৈরি করুনwasm.buildInstance()
এফএমজেড দ্বারা সমন্বিত।
তাহলে ফোন করোfib
ফাংশন এই wasm মডেল দৃষ্টান্ত, যথাঃret = instance.callFunction('fib', input)
.
এই পরীক্ষার কৌশলটি শুধুমাত্র বাস্তব বট পরীক্ষার জন্য ব্যবহার করা যেতে পারে। জাভাস্ক্রিপ্ট মাল্টি-থ্রেডিং ফাংশনগুলি এখনও পর্যন্ত ব্যাকটেস্টিং সমর্থন করে না।
wasm
এবংJavaScript
বাস্তবায়ন তুলনা, চূড়ান্ত বাস্তবায়ন ফলাফলঃ
2023-03-06 11:00:33 infomation #2 wasm fib: 832040 elapsed: 13283.773019
2023-03-06 11:00:33 infomation #1 javascript fib: 832040 elapsed: 21266.326974
মনে হচ্ছেwasm
এতে কম সময় লাগে এবং এটি আরও ভাল।