Khi phát triển các chiến lược trên FMZ sử dụng ngôn ngữ JavaScript, vì kiến trúc chiến lược được khảo sát.exchange.Go
function được sử dụng để thực hiện các cuộc gọi đồng thời đến một số giao diện, để đáp ứng các yêu cầu của một số kịch bản đồng thời. Nhưng nếu bạn muốn tạo một luồng duy nhất để thực hiện một loạt các hoạt động, nó là không thể. Ví dụ như ngôn ngữ Python, sử dụngthreading
thư viện để làm một số thiết kế đồng thời.
Dựa trên yêu cầu này, nền tảng FMZ đã nâng cấp lớp dưới của hệ thống.
Tiếp theo, tôi sẽ đưa bạn để hiểu từng chức năng một một.
Các__Thread
function có thể tạo một chủ đề và thực thi một hàm đồng thời. ví dụ, bạn cần tạo một hàm đồng thờifunc1
, điều gì làm chofunc1
Chúng ta có thể để nó tích lũy từ 0 đến 9. Để xem quá trình tích lũy dần dần, chúng ta sử dụng vòng lặp for trong hàm func1 để tạm dừng mỗi lần (chức năng Sleep được sử dụng để ngủ trong một số lượng nhất định của milliseconds) trong một khoảng thời gian nhất định.
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)
}
Trong các ứng dụng thực tế, chúng ta có thể thực hiện các yêu cầu http đồng thời như thế này:
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))
})
}
Trong ví dụ trên, chúng tôi đã sử dụng__threadJoin
chức năng trong chức năng chính cuối cùng để chờ cho các luồng đồng thời để hoàn thành thực thi.ret
nhận được giá trị trả về của__threadJoin
hàm, và chúng tôi in giá trị trả về, chúng tôi có thể quan sát các kết quả cụ thể của việc thực hiện chuỗi đồng thời.
// 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
}
Chúng tôi vẫn sử dụng ví dụ ngay bây giờ, sau khi tạo một chủ đề, bạn có thể buộc phải chấm dứt việc thực hiện chủ đề sau khi chờ đợi 1 giây.
Truyền thông giữa các chuỗi chủ yếu sử dụng__threadPostMessage
chức năng và__threadPeekMessage
Hãy xem ví dụ đơn giản sau:
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)
}
}
Các__threadPostMessage
function được sử dụng để gửi tin nhắn đến một thread. Parameter đầu tiên là ID của thread cụ thể để gửi đến, và tham số thứ hai là tin nhắn để gửi, có thể là một chuỗi, một giá trị, một mảng, hoặc một đối tượng JSON và vân vân. Tin nhắn có thể được gửi đến chủ đề chủ đề trong các hàm chủ đề đồng thời, và ID của chủ đề chủ đề được định nghĩa là 0.
Các__threadPeekMessage
function được sử dụng để theo dõi thông điệp được gửi bởi một chủ đề nhất định. Parameter đầu tiên là để theo dõi ID cụ thể của chủ đề. Parameter thứ hai có thể thiết lập thời gian hết thời gian (trong milliseconds), hoặc nó có thể được thiết lập thành -1, có nghĩa là chặn, và nó sẽ không trở lại cho đến khi có một thông điệp. Chúng ta có thể nghe thông điệp được gửi bởi chủ đề chính đến chủ đề hiện tại trong hàm chủ đề đồng thời, và ID của chủ đề chính được định nghĩa là 0.
Tất nhiên, ngoại trừ các luồng liên lạc đồng thời với luồng chính, luồng liên lạc đồng thời cũng có thể liên lạc trực tiếp với nhau.
Trong ví dụ trên,var id = __threadId()
được sử dụng, và__threadId()
hàm có thể nhận được ID của chủ đề hiện tại.
Ngoài giao tiếp giữa các chủ đề, các biến được chia sẻ cũng có thể được sử dụng để tương tác.
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
}
Điều trên là một minh chứng đơn giản của tất cả các hàm.
Địa chỉ chiến lược thử nghiệm này:https://www.fmz.com/strategy/401463
Một cái nhìn, bạn có thể không biết chiến lược thử nghiệm này làm gì. Nó không quan trọng, hãy giải thích nó. Trước tiên, hãy tìm hiểu WASM là gì.
Then the test strategy is to compare the execution efficiency of wasm and javascript, but when comparing, the two execution methods can be executed successively, and the time-consuming of each is counted. It is also possible to allow the two execution methods to execute concurrently, and the statistics are time-consuming. Now that the underlying concurrency implementation of the JavaScript language strategy has been supported, the test strategy uses a concurrent method to compare naturally and compare the execution speed of the same algorithm.
- Algorithm of C language version, fib function
// thuật toán tái diễn của số Fibonacci trong ngôn ngữ C int fib ((int f) { if (f < 2) trả về f; trả lại fib ((f - 1) + fib ((f - 2); }
- JavaScript language version of the algorithm, fib function
// Một thuật toán tái diễn cho cùng một số Fibonacci, được viết bằng JavaScript hàm fib ((f) { if (f < 2) trả về f trả lại fib ((f - 1) + fib ((f - 2) }
It can be seen that the logic of the two fib function algorithms is exactly the same. The following is the source code of the test strategy:
chức năng chính (() {
// Để dễ dàng nhìn thấy mã, tôi viết bình luận về mã sau trực tiếp:
cho cycle = 100 // Thử nghiệm thực hiện vòng lặp 100 lần
let input = 30 // Các thông số sẽ được truyền đến hàm fib thuật toán
để các chủ đề = [
__Thread(function(cycle, input) { // Một thread được tạo đồng thời để thực hiện tính toán bằng cách sử dụng phiên bản JavaScript của hàm fib
hàm fib ((f) { // Các thuật toán cụ thể được sử dụng để kiểm tra, hàm fib
if (f < 2) trả về f
trả lại fib ((f - 1) + fib ((f - 2)
}
để ret = 0
cho (để i = 0; i < chu kỳ; i++) { // vòng lặp cho 100 lần
ret = fib(input); // Gọi hàm fib của ngôn ngữ JavaScript
Log ((
__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
})
}
Simply put, WASM is a program code with higher execution efficiency. In the example, we convert the c language code of "Fibonacci number recursive algorithm" into WASM. The process is like this:
1. Compile a piece of C language function code into wasm code.
We can use the website to convert: https://wasdk.github.io/WasmFiddle/
// Algorithm recursive của số Fibonacci trong ngôn ngữ C int fib ((int f) { if (f < 2) trả về f; trả lại fib ((f - 1) + fib ((f - 2); }
2. Further encode the wasm code into a hex string.
The following commands can be used:
python -c
The encoded hex string is ```let data = 'data:hex,0061736d0100000001868...``` in the code.
3. Then parse it into a wasm model through the function ```wasm.parseModule()``` integrated by FMZ.
4. Create a wasm model instance through the function ```wasm.buildInstance()``` integrated by FMZ.
5. Then call the ```fib``` function in this wasm model instance, namely: ```ret = instance.callFunction('fib', input)```.
## Create a real bot to run the test
This test strategy can only be used for real bot testing. JavaScript multi-threading functions do not support backtesting so far.
```wasm``` and ```JavaScript``` execution comparison, the final execution results:
2023-03-06 11:00:33 thông tin #2 wasm fib: 832040 đã hết hạn: 13283.773019
2023-03-06 11:00:33 infomation #1 javascript fib: 832040 đã hết hạn: 21266.326974
It seems that
Wasm