С# заблокированный декремент для короткого значения

Я провожу некоторые эксперименты, и мне нужно атомарно уменьшить 16-битное (короткое) значение в С#. Значение хранится в неуправляемой памяти, и не составляет труда убедиться, что значение выровнено по 16-битной границе виртуальной памяти.

Я обнаружил, что winnt.h (kernel32) предоставляет такую ​​функцию: https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockeddecrement16

Однако, когда я пытаюсь p/вызвать эту функцию из своего приложения .NET, я получаю следующую ошибку:

Unable to find an entry point named 'InterlockedDecrement16' in DLL 'kernel32.dll'.

Код импорта метода выглядит так:

[DllImport("kernel32.dll")]
public static extern int InterlockedDecrement16(ref short addend);

Почему я получаю эту ошибку, и видите ли вы другие альтернативы interlocked16 p/invoke, когда для этого нет встроенных компиляторов в C# (только 32-разрядные и 64-разрядные версии доступны на Заблокировано)


person DEHAAS    schedule 03.11.2020    source источник
comment
Вероятно, вы можете добиться того же, не используя pinvoke, просто добавив lock вокруг своего атомарного значения.   -  person Liam    schedule 03.11.2020
comment
@Liam Да, извините, если вопрос был слишком расплывчатым. Цель состоит в том, чтобы найти решение для декремента с большей производительностью, чем блокировка.   -  person DEHAAS    schedule 03.11.2020
comment
Опишите лучшую производительность? Замок должен быть в порядке. Если вы хотите, чтобы он был атомарным, вам всегда нужна какая-то блокировка, чтобы предотвратить состояние гонки? Декремент должен занимать доли тика... Как быстро вы хотите, чтобы это было?!   -  person Liam    schedule 03.11.2020
comment
Кроме того, вызов pinvoke никоим образом не улучшит производительность. Это, вероятно, просто замедлит работу вашего приложения, будет использовать больше памяти, процессора и т. д.   -  person Liam    schedule 03.11.2020
comment
Кажется, эта функция доступна только как встроенная функция компилятора и не имеет соответствующей реальной функции в kernel32.   -  person Evk    schedule 03.11.2020
comment
Отвечает ли это на ваш вопрос? Быстрый (самый быстрый) счетчик потоков C#   -  person Liam    schedule 03.11.2020
comment
@JeroenMostert Спасибо, это был и мой вывод. Мне нужно выполнить CompareExchange большей области памяти (64-разрядной) для других целей, эта область должна содержать короткое значение, поэтому я не могу вместо этого просто использовать значение int32. Это потребовало бы от меня вызова операции CAS на чем-то большем, чем 64-разрядная версия, которая снова представлена ​​в winnt.h, но не в среде выполнения .NET, насколько я могу найти.   -  person DEHAAS    schedule 03.11.2020
comment
@Liam Нет, это не отвечает на вопрос, и нет, Interlocked.Decrement нельзя использовать для краткой ссылки на значение.   -  person DEHAAS    schedule 03.11.2020
comment
Нет, его можно использовать с Int32, который является допустимым short. Int32 содержит все значения для шорта и (как я уже сказал) существует неявное преобразование   -  person Liam    schedule 03.11.2020
comment
@Liam: нет явных или иных преобразований из ref Int32 в ref Int16 и наоборот. Подумайте немного о том, как может работать такая операция, и вы увидите, что невозможно реализовать атомарное обновление 16-битного значения, если все, что у вас есть, — это примитив, который атомарно обновляет 32-битное значение. Что бы C# ни предлагал в отделе неявного преобразования, это не имеет значения. Возможно, вы упускаете из виду, что это значение хранится в неуправляемой части памяти — мы не можем просто расширить значение.   -  person Jeroen Mostert    schedule 03.11.2020
comment
Что вы можете сделать, так это определить необходимый байт («заблокировать xadd» и т. д., например, компилируя небольшой образец C/C++) и построить на нем функцию C#, что-то вроде этого: stackoverflow.com/questions/18836120/. Конечно, это зависит от процессора.   -  person Simon Mourier    schedule 03.11.2020
comment
Большое спасибо всем здесь. Сейчас я изучаю создание оболочки C++/CLR для функции InterlockedDecrement16. Однако я вижу некоторые странные характеристики производительности (stackoverflow.com/questions/64699059/). Поскольку я не могу пометить комментарий как ответ, пожалуйста, не стесняйтесь публиковать свои идеи в качестве ответа на этот вопрос.   -  person DEHAAS    schedule 05.11.2020