Бросание исключений и Burst компилятор (2024)

(Russian translation from English by Maxim Voloshin)

Burst компилятор Unity навязывает использование интересного подмножества C#. Правило “никаких управляемых объектов” не всегда справедливо. Сегодня мы посмотрим на исключения (Exception), которые являются управляемыми объектами, но частично поддерживаются Burst. Что же разрешено, а что запрещено? Читайте дальше, чтобы узнать.

Документация Burst гласит:

Burst работает с подмножеством .NET, которое не допускает использования любых управляемых объектов/ссылочных типов в вашем коде (классы в C#).

Позже указан список запрещенных типов:

string так как это управляемый тип

И еще раз позже:

Любые методы, относящиеся к управляемым объектам (например, методы, использующие string и т.д.)

Атрибут [BurstDiscard] может быть полезен, когда вы хотите использовать эти самые управляемые объекты

При запуске некоторого кода на полноценном C# (не внутри кода, компилируемого через Burst) Вы можете захотеть использовать некоторые управляемые объекты, но при этом не компилировать эти части кода при использовании Burst.

Все выглядит так, словно исключения, которые являются классами и, стало быть, управляемыми объектами еще и принимающие как аргумент строку с сообщением, не могут быть использованы в коде, скомпилированном Burst. Однако, оказывается есть исключение (извините за каламбур) из этих правил, которое позволяет исключениям и строкам частично работать.

Давайте попробуем написать несколько тестовых задач в Job System, которые используют исключения и строки

using System;using Unity.Burst;using Unity.Jobs;using UnityEngine;class TestScript : MonoBehaviour{ [BurstCompile] struct ExceptionJob : IJob { public void Execute() { throw new ArgumentException("boom"); } } [BurstCompile] struct BeginExceptionJob : IJob { public int I; public void Execute() { throw new ArgumentException("boom" + I); } } [BurstCompile] struct EndExceptionJob : IJob { public int I; public void Execute() { throw new ArgumentException(I + "boom"); } } [BurstCompile] struct MiddleExceptionJob : IJob { public int I; public void Execute() { throw new ArgumentException(I + "boom" + I); } } void Start() { new ExceptionJob().Schedule().Complete(); new BeginExceptionJob { I = 10 }.Schedule().Complete(); new EndExceptionJob { I = 10 }.Schedule().Complete(); new MiddleExceptionJob { I = 10 }.Schedule().Complete(); }}

Теперь мы запустим это в Unity 2019.1.3f1 и Burst 1.0.0 на macOS и посмотрим на результат. Во-первых, это прекрасно компилируется в редакторе и билд для macOS тоже работает. Никаких ошибок или предупреждений. Если запустить macOS приложение, то мы увидим в консоли следующее:

System.ArgumentException: boomThis Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Enable Burst Compiler) to inspect full exceptions & stacktraces.(Filename: Line: -1)System.ArgumentException: boomThis Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Enable Burst Compiler) to inspect full exceptions & stacktraces.(Filename: Line: -1)System.ArgumentException: boomThis Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Enable Burst Compiler) to inspect full exceptions & stacktraces.(Filename: Line: -1)System.ArgumentException: boomThis Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Enable Burst Compiler) to inspect full exceptions & stacktraces.(Filename: Line: -1)

Обратите внимание, что все четыре задачи бросили исключение System.ArgumentException, содержащее сообщение boom. Ни одна из конкатенаций не отработала и мы остались только со строкой "boom".

Чтобы выяснить почему, давайте откроем Burst панель в Инспекторе и посмотрим на сгенерированный ассемблерный код для каждой из задач:

; ExceptionJobmovabs rax, offset .Lburst_abort_Ptrmov rax, qword ptr [rax]movabs rdi, offset .Lburst_abort.error.idmovabs rsi, offset .Lburst_abort.error.messagejmp rax; BeginExceptionJobmovabs rax, offset .Lburst_abort_Ptrmov rax, qword ptr [rax]movabs rdi, offset .Lburst_abort.error.idmovabs rsi, offset .Lburst_abort.error.messagejmp rax; EndExceptionJobmovabs rax, offset .Lburst_abort_Ptrmov rax, qword ptr [rax]movabs rdi, offset .Lburst_abort.error.idmovabs rsi, offset .Lburst_abort.error.messagejmp rax; MiddleExceptionJobmovabs rax, offset .Lburst_abort_Ptrmov rax, qword ptr [rax]movabs rdi, offset .Lburst_abort.error.idmovabs rsi, offset .Lburst_abort.error.messagejmp rax

Все четыре задачи были скомпилированы в абсолютно одинаковый код. Отсутствуют инструкции чтения значения переменной I и его конкатенации со строкой "boom". Вместо этого мы видим, что .Lburst_abort.error.id и .Lburst_abort.error.message выводятся вследствие возникновения исключения, и программа переходит в .Lburst_abort_Ptr. Для того чтобы узнать больше об этих символах, давайте посмотрим на следующий ассемблерный код:

.Lburst_abort.error.id: .asciz "System.ArgumentException" .size .Lburst_abort.error.id, 25 .type .Lburst_abort.error.message,@object.Lburst_abort.error.message: .asciz "boom" .size .Lburst_abort.error.message, 5 .type .Lburst_abort_Ptr,@object .local .Lburst_abort_Ptr .comm .Lburst_abort_Ptr,8,8 .type .Lburst_abort.function.string,@object.Lburst_abort.function.string: .asciz "burst_abort" .size .Lburst_abort.function.string, 12 .section .debug_str,"MS",@progbits,1

Здесь мы видим, что .Lburst_abort.error.id содержит ASCII (.asciz) строку "System.ArgumentException", размер которой (.size) равен 25, что соответствует количеству символов в строке плюс символ конца строки NUL.

.Lburst_abort.error.message содержит ASCII строку "boom", размер которой равен 5 все по тем же причинам.

.Lburst_abort_Ptr внутри .Lburst_abort.error.message это адрес в памяти, по которому перейдет выполнение программы во время бросания исключения.

Таким образом, когда бросается исключение в коде, скомпилированном через Burst, указатель на строку с типом исключения (System.ArgumentException, в данном случае) и указатель на строку с сообщением (boom) будут записаны в определенные регистры и выполнение программы перейдет по адресу.Lburst_abort_Ptr, где исключение, по всей видимости, обрабатывается чтением из этих регистров.

При этом не происходит абсолютно никаких выделений памяти. Только хранение указателей на строковые литералы, сохраненные в сегменте данных. Это возможная причина того, почему не сработала конкатенация строк. Так как это потребует дополнительных аллокаций, в перспективе динамически растущих, и последующее освобождения памяти, когда исключение будет обработано.

Так что не стесняйтесь использовать исключения в Job System с Burst компилятором до тех пор, пока сообщение является строковым литералом или конкатенации не нужны. Только имейте в виду, что catch и finally нельзя использовать с Burst, следовательно, бросание исключения всегда будет приводить к фатальной ошибке.

Бросание исключений и Burst компилятор (2024)
Top Articles
Tate | Draft-day decisions affect Illini's reputation
Spoilers! How Nicolas Cage's mom inspired his 'Longlegs' 'boogeyman'
Spasa Parish
Rentals for rent in Maastricht
159R Bus Schedule Pdf
Sallisaw Bin Store
Black Adam Showtimes Near Maya Cinemas Delano
Espn Transfer Portal Basketball
Pollen Levels Richmond
11 Best Sites Like The Chive For Funny Pictures and Memes
Things to do in Wichita Falls on weekends 12-15 September
Craigslist Pets Huntsville Alabama
Paulette Goddard | American Actress, Modern Times, Charlie Chaplin
Red Dead Redemption 2 Legendary Fish Locations Guide (“A Fisher of Fish”)
What's the Difference Between Halal and Haram Meat & Food?
R/Skinwalker
Rugged Gentleman Barber Shop Martinsburg Wv
Jennifer Lenzini Leaving Ktiv
Justified - Streams, Episodenguide und News zur Serie
Epay. Medstarhealth.org
Olde Kegg Bar & Grill Portage Menu
Cubilabras
Half Inning In Which The Home Team Bats Crossword
Amazing Lash Bay Colony
Juego Friv Poki
Dirt Devil Ud70181 Parts Diagram
Truist Bank Open Saturday
Water Leaks in Your Car When It Rains? Common Causes & Fixes
What’s Closing at Disney World? A Complete Guide
New from Simply So Good - Cherry Apricot Slab Pie
Drys Pharmacy
Ohio State Football Wiki
Find Words Containing Specific Letters | WordFinder®
FirstLight Power to Acquire Leading Canadian Renewable Operator and Developer Hydromega Services Inc. - FirstLight
Webmail.unt.edu
2024-25 ITH Season Preview: USC Trojans
Metro By T Mobile Sign In
Trade Chart Dave Richard
Lincoln Financial Field Section 110
Free Stuff Craigslist Roanoke Va
Wi Dept Of Regulation & Licensing
Pick N Pull Near Me [Locator Map + Guide + FAQ]
Crystal Westbrooks Nipple
Ice Hockey Dboard
Über 60 Prozent Rabatt auf E-Bikes: Aldi reduziert sämtliche Pedelecs stark im Preis - nur noch für kurze Zeit
Wie blocke ich einen Bot aus Boardman/USA - sellerforum.de
Infinity Pool Showtimes Near Maya Cinemas Bakersfield
Dermpathdiagnostics Com Pay Invoice
How To Use Price Chopper Points At Quiktrip
Maria Butina Bikini
Busted Newspaper Zapata Tx
Latest Posts
Article information

Author: Dr. Pierre Goyette

Last Updated:

Views: 6096

Rating: 5 / 5 (50 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Dr. Pierre Goyette

Birthday: 1998-01-29

Address: Apt. 611 3357 Yong Plain, West Audra, IL 70053

Phone: +5819954278378

Job: Construction Director

Hobby: Embroidery, Creative writing, Shopping, Driving, Stand-up comedy, Coffee roasting, Scrapbooking

Introduction: My name is Dr. Pierre Goyette, I am a enchanting, powerful, jolly, rich, graceful, colorful, zany person who loves writing and wants to share my knowledge and understanding with you.