7

голосов
2

ответ
196

Просмотры

Может C # оператора генерировать ноны подключенного MSIL

Речь идет о C # спецификации языка и спецификации CIL языка, а также компании Microsoft и C # поведения компилятора Моно. Я строю некоторые инструменты анализа кода (независимо от того, что), которые работают на КСС. Учитывая несколько примеров коды, я заметил, что заявления коды (попытаться / поймать, IfElse, ifthen, петлю, ...) генерировать подключенные блоки MSIL. Но я хотел бы, чтобы убедиться, что я не могу писать C # код конструкции, которое дает Неподключённый MSIL. Более конкретно, я могу написать любое заявление, C #, который переводит с (что-то подобное): IL_0000: IL_0001: IL_0002: // дыра IL_001a: IL_001b: Я уже пробовал некоторые странные вещи, используя Гото и вложенные циклы, но, может быть, я не так сумасшедший, как некоторые пользователи будут.
Regis Portalez
5

голосов
2

ответ
2.5k

Просмотры

только NuGet содержимого пакета файлов

Я хотел бы создать NuGet пакет (от некоторого C # проекта), но я не хочу, чтобы встроить DLL сгенерированного, но только некоторые статические файлы вместо этого. Я добавил тег в конце моего nuspec файла, но NuGet команды пакета продолжает вставлять project.dll в пакете. Дело в том, что я не хочу, чтобы это длл будет опубликован. Есть ли способ сделать это? Спасибо, Режис
Regis Portalez
3

голосов
1

ответ
401

Просмотры

Читайте Память в SharedArrayBuffer

В попытке распараллелить обработку на больших TypedArrays, я пытался использовать расширение имени MOZILLA SharedArrayBuffer. Эти объекты позволяют одновременно рабочие (или основной поток) для обработки и ту же память (которая не становится недоступной для вызывающего PostMessage). К сожалению, оказывается, что я не могу прочитать память о тех объектах, я не могу использовать DataViews на них. Я попытался следующие с DataViews, чтобы избежать целых копий буфера: вар ArrayBuffer = новый SharedArrayBuffer (4); // 4 байта вар DataView = новый DataView (новый SharedArrayBuffer (4)); // с ошибкой ниже // некоторым использования здесь вар первого = dataView.getFloat32 (0), который завершается с ошибкой: TypeError: DataView: ожидается ArrayBuffer, получил SharedArrayBuffer я мог прочитать память, сделав в TypedArray обратно из буфера, но этот клон будет память, и, следовательно, испортит прирост производительности памяти совместного использования, как это, кажется, есть небольшие накладные расходы, такие как предложил эту ошибку ответ, но тогда я должен знать тип заранее. Есть ли решение этой проблемы?
Regis Portalez
3

голосов
1

ответ
263

Просмотры

Внутреннее представление памяти Fortran ALLOCATABLE

Я хотел бы знать, что такое внутреннее представление памяти фортрановского размещаемого массива. Я понимаю, это немного сложнее, чем сырой указатель, так как форма и ранги должны быть сохранены, а также. Я также предполагаю, что это зависит от конкретной реализации, так как я не нахожу данные в стандарте Fortran 2003. Тем не менее, я хотел бы знать, какие структуры используется для представления распределяемых массивов (даже только один компилятора). Я знаю, что вопрос немного широк, но любая помощь будет принята с благодарностью.
Regis Portalez
6

голосов
2

ответ
161

Просмотры

указатели на указатели - причина потери производительности

Я ответил на этот вопрос, и заметил, что я считаю, как странное поведение компилятора. Я первый написал эту программу (как часть моего ответа там): класс Vector {частные: двойной ** PTR; общественности: Vector (двойной ** _ptr): PTR (_ptr) {} встроенный двойной & оператор [] (Уст INT iIndex) сопзЬ {возвращение * PTR [iIndex]; }}; ехЬегп «С» INT тест (Const дважды а); INT основных () {двойной а [2] = {1,0, 2,0}; Вектор в ((двойная **) & а); двойная а1 = ва [0]; тест (a1); двойная а2 = ва [0]; тест (а2); }, Который генерирует две команды нагрузки при компиляции с: звоном -O3 -S -emit-LLVM main.cpp -o main.ll Это можно увидеть в LLVM-IR (и может рассматриваться в сборке): определить I32 @main () {# 0 запись:% a.sroa.0.0.copyload = нагрузка двойной *, двойные ** bitcast ([2 х двойной] * @ _ZZ4mainE1a удвоить **), выравнивание 16% 0 = нагрузка двойной, двойной *% a.sroa.0.0.copyload, выровнять 8,! tbaa! 2% call1 = хвост называет I32 @test (двойной% 0) = 1% нагрузкой двойным, двойным *% а. sroa.0.0.copyload, выравнивать 8,! tbaa! 2% call3 = хвост называют i32 @test (двойной% 1) RET i32 0} Я ожидал бы только одну команду загрузки, так как никакой функции с побочным эффектом на память была вызвана, и я не связывал этот объект что-то с побочными эффектами. В самом деле, при чтении программы, я просто ожидаю два вызовов для проверки (1.0); так как мой массив постоянно в памяти, и все, что может быть встраиваемыми правильно. Чтобы быть уверенным, я заменил двойной указатель на простой указатель: класс Vector {частные: двойной * PTR; общественности: Vector (двойной * _ptr): PTR (_ptr) {} встроенный двойной & оператор [] (Уст INT iIndex) сопзЬ {возвращение PTR [iIndex]; }}; Экстерн «C» INT тест (Const дважды а); INT основных () {двойной а [2] = {1,0, 2,0}; Вектор в (а); двойная а1 = ва [0]; тест (a1); двойная а2 = ва [0]; тест (а2); } Сост с одной и той же линии, я получаю ожидаемый результат: определить i32 @main () # 0 {запись:% call1 = хвост называют I32 @test (двойной 1.000000e + 00)% call3 = хвост называют i32 @test (двойной 1.000000 е + 00) RET i32 0}, который выглядит как способ лучше оптимизирован :) Мой вопрос таким образом: Какая причина мешает компилятору выполнять ту же подстановку на первом образце кода? Есть что двойные указатели? 000000e + 00)% call3 = хвост называют i32 @test (двойной 1.000000e + 00) RET i32 0} Который выглядит намного лучше оптимизировано :) Мой вопрос таким образом: Какая причина мешает компилятору выполнять ту же подстановку на первый код образец? Есть что двойные указатели? 000000e + 00)% call3 = хвост называют i32 @test (двойной 1.000000e + 00) RET i32 0} Который выглядит намного лучше оптимизировано :) Мой вопрос таким образом: Какая причина мешает компилятору выполнять ту же подстановку на первый код образец? Есть что двойные указатели?
Regis Portalez
1

голосов
1

ответ
179

Просмотры

недействительный порядковое устройство на cudaMemPrefetchAsync

Я бег образца CUDA игрушки на моем GeForce 1080 Ti (Паскаль) на Windows 10 и CUDA 9.2. Цель заключается в проверке cudaMemPrefetchAsync к CPU, так как он должен работать. Тем не менее, я получаю ошибку CUDA (недействительный порядковое устройства) на данной линии. # include "cuda_runtime.h" # include "device_launch_parameters.h" # include # include заполнения пустот (INT * а, Int вал, Int N) {для (Int к = 0; к <N; ++ к) {а [ K] = Val; }} __Global__ недействительными добавить (интермедиат * а, б INT *, Int N) {для (INT I = threadIdx.x + blockIdx.x * blockDim.x; г <N; I + = blockDim.x * gridDim.x) {а [я] + = Ь [I]; }} Рядный недействительным чек (cudaError_t заблуждается, Const символ * файл, внутр строку) {если (ERR = cudaSuccess!) {:: fprintf (STDERR, "ОШИБКА% S [% D]:% s \ п", файл, линия, cudaGetErrorString (ERR)); прервать (); }} #Define CUDA_CHECK (ERR) делают {чек (ERR, __FILE__, __LINE__); } В то время как (0) INT основных () {INT DeviceId; CUDA_CHECK (cudaGetDevice (& DeviceId)); сопзЬ Int N = 1024 * 1024 * 32; INT * а * Ь; CUDA_CHECK (cudaMallocManaged (& A, N * SizeOf (INT))); CUDA_CHECK (cudaMallocManaged (& B, N * SizeOf (INT))); CUDA_CHECK (cudaMemPrefetchAsync (A, N * SizeOf (INT), cudaCpuDeviceId)); // программа перерывы здесь CUDA_CHECK (cudaMemPrefetchAsync (б, N * SizeOf (INT), cudaCpuDeviceId)); заполнить (а, 1, N); заполнить (а, 2, Н); CUDA_CHECK (cudaMemPrefetchAsync (A, N * SizeOf (INT), DeviceId)); CUDA_CHECK (cudaMemPrefetchAsync (б, N * SizeOf (INT), DeviceId)); добавить (а, б, Н); CUDA_CHECK (cudaGetLastError ()); CUDA_CHECK (cudaDeviceSynchronize ()); возвращать 0; } Является ли это аппаратный / драйвер / ограничение ОС? Могу ли я просто игнорировать эту ошибку?
Regis Portalez
4

голосов
2

ответ
58

Просмотры

Перегрузки, родовые и ограничение типа: разрешение метода

Рассмотрим следующий фрагмент кода, показывая дженерики и перегруженные функции: с помощью системы; Пространство имен {Test_Project интерфейс Интерфейс общественной {пустоты F (); } Общественного класса U: Интерфейс {общественного недействительными F () {}} Класс общественного класса, где Т: Интерфейс {государственной статической силы OverloadedFunction (Т а) {Console.WriteLine ( "Т"); аф (); } Государственной статической силы OverloadedFunction (U а) {Console.WriteLine ( "U"); аф (); }} Класс Program {государственной статической силы Invoke (пример U) {Class.OverloadedFunction (экземпляр); } Статической силы основных (String [] арг) {Invoke (новый U ()); }}} Я бы сказал, что не компилируется, поскольку у меня есть два подходящих методов для кандидатов OverloadedFunction. Однако это делает и печатает «U». В сгенерированном IL, я могу видеть, что: .method общественности hidebysig статической силы ( 'экземпляр' класс Test_Project.U) Invoke CIL удалось {// Метод начинается в RVA 0x2085 // Код Размер 7 (0x7) .maxstack 8 IL_0000: ldarg +0,0 IL_0001: вызов недействительным класса Test_Project.Class`1 :: OverloadedFunction (класс Test_Project.U) IL_0006: в отставке} // конец метода программы :: Invoke означает, что C # компилятор разрешен вызов OverloadedFunction на вызов вместо callvirt, которые потребовались бы на «общий» функции. Я могу предположить, что метод «U» является лучшим кандидатом с точки зрения компилятора, но я не могу определенно объяснить, почему ... Я d действительно хотел бы понять, что произошло здесь, и я понятия не имеют. Но это становится еще более странным, если учесть эту модифицированную версию сниппета, где мы вводим еще один уровень косвенности: с помощью системы; Пространство имен {Test_Project интерфейс Интерфейс общественной {пустоты F (); } Общественного класса U: Интерфейс {общественного недействительными F () {}} Класс V общественности: U {} Класс общественного класса, где Т: Интерфейс {государственной статической силы OverloadedFunction (Т а) {Console.WriteLine ( "Т"); аф (); } Государственной статической силы OverloadedFunction (U а) {Console.WriteLine ( "U"); аф (); }} Класс программы {государственной статической силы (экземпляр V) Вызвать {Class.OverloadedFunction (экземпляр); } Статической силы основных (String [] арг) {Invoke (новый V ()); }}} Я бы ожидать, что эта программа все еще напечатать «U», как «V» являются «U» по наследству. Но он печатает 'T', как показано по MSIL: .method общественного hidebysig статической силы Invoke (класс Test_Project.V 'экземпляр') CIL удалось {// Метод начинается в RVA 0x208d // Код Размер 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: вызов аннулируется класс Test_Project.Class`1 :: OverloadedFunction IL_0006 (0!): RET} // конец метода программы :: Invoke это означает, что общая версия была предпочитается компилятором C #. Может кто-нибудь объяснить, пожалуйста, каковы правила перегруженного разрешения методов, когда дело доходит до общих параметров и наследования?
Regis Portalez
3

голосов
1

ответ
315

Просмотры

MSIL Испустите статический массив в динамическом типе

Я пытаюсь создать новый тип, используя Reflection.Emit (в C #). Код, который я хочу, чтобы создать нечто подобное для общественного класса {государственной статической ИНТ [] A = новый INT [] {1, 2, 3}; } Сначала я попытался определить поле, а затем установить его значение: Var FB = tb.DefineField ( "А", FieldAttributes.Public | FieldAttributes.Static); fb.SetValue (нуль, новый INT [] {1, 2, 3}); но он не работает, так как SetValue поддерживается только для простых типов (INT, поплавка, ...). Теперь я пытаюсь использовать DefineInitializedData (гораздо больше кода, который не работает ...), но он не генерирует правильный код IL.
Regis Portalez
2

голосов
0

ответ
59

Просмотры

Test if Generic Method can be invoked on Parameters list

Скажем, у меня есть универсальный метод (получено от родительского типа с отражением): пустота MyType :: MyMethod (T [], Int, Int) Я хочу знать, могу ли я вызвать этот метод на некоторый списке типов: байты [], int32 , int32 Очевидно, что ответ утвердительный. Однако я хотел бы найти общий способ найти лучшие перегрузки (среди нескольких дженерик) соответствие списка параметров. Я могу легко получить все методы:. MyType.GetMethods () Где (т => m.Name == "MyMethod"), то фильтр для соответствия подсчета параметров:. .Гда (т => m.GetParameters () Count () = = 3), но тогда я заблокирован. [EDIT, как это предусмотрено в комментарии] метода вара = TypeOf (массив) .GetMethods (); вар sortMethods = methods.Where (м => m.Name == "Сортировка"); кандидаты вар = sortMethods.Where (м => m.GetParameters () Count () == 3.); вар parameterTypes = новый тип [] {TypeOf (байт) .MakeArrayType (), TypeOf (Int32), TypeOf (Int32)}; Еогеасп (вар м кандидатов) {// найти лучший матч} я получаю 4 метод: И я не знаю, как программно найти лучший матч.
Regis Portalez
2

голосов
1

ответ
67

Просмотры

Есть ли инструкция замаскированной-смесь на PowerPC?

Я пытаюсь выполнить замаскированную смесь (по типам __vector) на PowerPC (Power 8). При взгляде на встроенные функции (список здесь) Я могу видеть вектор выбора, но ничего для слияния. На процессорах x86 я знаю сущностные _mm256_blendv_ps, и я искал что-то подобное. Спасибо!
Regis Portalez
2

голосов
2

ответ
195

Просмотры

На PowerPC, есть ли эквивалент movemask корпорации Intel встроенных функций?

Я хотел бы объединить все элементы в __vector BOOL долго долго в один INT, в котором каждый бит установлен в наиболее значащего бита входного вектора, например: __vector BOOL долго долго VCMP = vec_cmplt (а, б); INT packedmask = / * некоторая функция ЗДЕСЬ * / (VCMP); с packedmask = х | у | 0000000000000000 .... где х равен 1, если vcmd [0] = 0xFFFFF ... или 0, если VCMP [0] = 0; то же самое для у. На разведданные, мы можем добиться этого с помощью инструкции _mm_movemask (внутренней для Intel), есть ли способ сделать то же самое на PowerPC? Спасибо за любую помощь
Regis Portalez
12

голосов
4

ответ
1.1k

Просмотры

Может быть сохранена точка репутации прибыли на другой день (помещён)?

Скажем, я заработал 200 очков репутации сегодня (дневной лимит), и я все еще получаю upvotes. Где заработанные пункты идут для тех, кто поздно upvotes? Являются ли они потеряли, или они помещён и будут начислены завтра?
Regis Portalez
6

голосов
1

ответ
188

Просмотры

Почему дополнительный целочисленный тип среди короткий / INT / долго?

До недавнего времени я считал, что «длинные» было то же самое, как «междунар» из-за исторических причин и настольных процессоров, которые все имеют по крайней мере 32 бита (и имел проблемы только с этим «надуть», так как только развивается на 32 бита машин). Читая это, я обнаружил, что, по сути, стандарт C определяет тип INT, чтобы быть по крайней мере, int16, в то время как «длинные», как предполагается, по крайней мере, int32. На самом деле в списке Short знаковый целочисленный тип. Способный, содержащий, по меньшей мере [-32767, +32767] Диапазон Базовый знаковый целочисленный тип. Способный, содержащий, по меньшей мере [-32767, +32767] диапазон; Длинные знаковый целочисленный тип. Способный содержащий, по меньшей мере, на [-2147483647, +2147483647] Диапазон Давным целочисленный тип. Способный, содержащий, по меньшей мере [-9223372036854775807, +9223372036854775807] диапазон; всегда есть непустые пересечения, и поэтому дубликат, независимо от реализации компилятора и платформы выбора. Почему стандарт ввел комитет дополнительного типа среди того, что может быть столь же просто, как полукокс / короткое замыкание / INT / длинный (или int_k, int_2k, int_4k, int_8k)? Был, что по историческим причинам, как, НКУ хх реализованы ИНТ 32 бита, а другой компилятор реализован как 16, или есть реальная техническая причина, почему я не хватает?
Regis Portalez