Как стать автором
Обновить

Комментарии 21

Если я правильно помню, то реализация memcpy еще каких-то лохматых 90-х годов на PC сначала копировала байтами до границы dword, а остальное — двойными словами. Мистер Дафф побывал и в стандартной библиотеке )
:14:10: error: duplicate case value '2'
    case 2: ++i;
         ^

https://godbolt.org/z/xhq74YMbP

Не хочу показаться снобом, но такое "пересечение" синтаксических блоков считаю просто недопустимым. Такие места, если они действительно обоснованны, должны быть прям явно развернуты в комментариях и с явным разрешением компилятору допускать такое. Это прям паттерн использования goto. Хотя против goto не имею особых аргументов, если он реально документирован и исполльзован на небольшом участке кода.

Так C-шный switch – это и есть goto, почти без синтаксического сахара.

И никакого снобизма в вашем подходе нет, понятность кода первична. Не думаю, что даже во времена Даффа таких кусков кода было много.

switch хорош, когда компилятор догадывается реализовать его, как indexed jump. Это особенно выгодно делать, если количество кейзов в свитче большое, и они компактно расположены — тогда индексная таблица будет небольшого размера с малым количеством дырок (указывающих на default, если он есть).
Кроме того (особенно важно для систем реального времени) — время перехода до любой метки свитча при таком способе одинаково, в отличие от цепочки условий.

Вроде компиляторы уже и цепочки условий нормально оптимизируют. А switch – худший оператор в C и C++ (в паскале был нормальный, в более поздних языках вроде тоже), не зря его сейчас исправляют – ну там, обязательный [[fallthrough]] для непустых кейсов, диапазоны...

Пользуюсь им, конечно, но только когда он очевидно улучшает читаемость и быстродействие.

Сишная концепция switch/case — очень в духе того времени и в духе области применения самого Си, хотя, безусловно, потенциально опасна, особенно для паскалистов или бейсичных программистов — при переходе с этих языков ошибки «проваливания» выполнения практически гарантированны. Но гибкость, которая в определенных условиях этим достигалась, стоила того, особенно в эпоху, когда памяти было мало. В Ассемблере в это время практиковались подпрограммы с несколькими точками входа — собственно, аналог такого свитча. И ничего, работали ). [fallthrough] же — конечно, костыль, но все же удобный. Не раздражает не по делу, ничего не стоит в рантайме, и позволяет все же сделать с редким ныне подвывертом, если очень нужно. Так что я за C-style switch. В Паскале помнится мне его порой очень не хватало.

Так я ж и говорю – goto практически в чистом виде. На тот момент был оправдан, да.

indexed jump

Только, к сожалению, работает это до сих пор похоже только в clang, либо в каких-то совсем экзотических кейсах.

Из-за таких вот древних штучек компилятору невозможно построить нормальное AST.
Видимо, для совместимости с такими фокусами 70-х есть какие-то хаки.

Всё же Duff's device переводится как метод Даффа. У слова device несколько значений.

Таки устройство/механизм, а не метод.

По ссылке статья, называющаяся «Устройство Даффа», начинается со слов «Метод Даффа (англ. Duff's device) в программировании — это ...». :) Ну и если посмотреть историю правок, то статью уже не раз переименовывали адепты той или иной версии.


Ну и сами посудите, какое из значений слова device больше подходит в данном случае. Подход к программированию — это устройство (механизм или электронный прибор) или всё же метод (план, приём, трюк)? Тем более, у device есть такое значение, и оно не какое-то редкое. Например, mnemonic devices — это мнемонические приёмы (а не мнемонические устройства, как полагает Google Translate).

В программировании методом обычно называют некоторую функцию принадлежащую объекту — больше непоняток. Ни разу не встречал mnemonic devices, но встречал mnemonic techniques. Devices, в контексте программирования, не относящегося непосредственно к железу, встречал только в контексте некоторых виртуальных устройств. Та же Тьюринг машина.
Да и кембриджский словарь показывает примеры в предлагаемом вам контексте a method that is used to produce a desired effect. Сказать что такое эффект Даффа без контекста нельзя (в отличие от вашего mnemonic devices или примера — marketing device), поэтому я все ещё считаю, что устройство — правильный перевод для этого: есть некоторая конструкция/механизм, с некоторой внутренней архитектурой и определенными эффектами. Даже собрать/разобрать можно. Туда же Jensen's device, который перевели как трюк Дженсена.

В программировании методом обычно называют некоторую функцию принадлежащую объекту — больше непоняток.

Да, но в данном случае мы говорим не о каком-то термине из программирования, а просто об обычном слове. Но, если хотите, можно перевести как приём или трюк, суть будет та же.


Ни разу не встречал mnemonic devices, но встречал mnemonic techniques.

Например, статья Mnemonic начинается с «A mnemonic device, or memory device, is ...». Да и в целом за пределами программистской литературы слово device в значении метод или приём встречается довольно часто. Скажем, Stylistic device.


Да и кембриджский словарь показывает примеры в предлагаемом вам контексте a method that is used to produce a desired effect. Сказать что такое эффект Даффа без контекста нельзя

Не очень понял, как появился «эффект Даффа». Процитированное определение означает лишь следующее: метод, используемый для получения желаемого результата (дословно — для произведения желаемого эффекта). Это не значит, что нужно слово device переводить как эффект.


есть некоторая конструкция/механизм, с некоторой внутренней архитектурой и определенными эффектами

Но ведь нет никакого устройства или механизма в буквальном смысле. Нет шестерёнок или проводов. А переносный смысл использовать ни к чему, когда у слова device уже есть значения метод, приём или трюк. Это не какая-то переводческая вольность, это просто дословный перевод по словарю. Вы же не будете спорить со словарём?


Как мне кажется, единственная причина, по которой это словосочетание вызывает споры, это то, что слово device в других значениях редко встречается в программистской литературе и другие значения непривычны. Ну так никого же не удивляет, что слово object переводится ещё и как протестовать, а virtual как фактический. У слов бывает несколько значений.

Предлагаю посмотреть, во что превращается код в обоих случаях после компиляции. Для этого воспользуемся Compiler Explorer'ом с компилятором gcc 11.1 для x86-64 без дополнительных опций.
вы уж если даете ссылку на godbolt, то давайте сразу шару на код и компиляцию. И заодно лучше запускать с оптимизациями, чтобы была видна разница в приближенном к реальности варианте. Её конечно же скорее всего не будет…

А вообще приятно жить во время, когда компиляторы стали достаточно умными, чтобы такие вот извращения были ни к чему.
Интересно, что помимо этого самого loop unrolling-а (занимается ли этим сейчас кто-нибудь?) duff's device нашел применение в Protothread-ах и coroutine-ах

Да там целая contiki os на нем построена

НЛО прилетело и опубликовало эту надпись здесь
Эм…
gcc -funroll-loops ..., не?

В конце 90-х знакомый оптимизировал рисование линий на CPU. Возникла идея - развернуть цикл на максимально возможную длину линии, а потом - делать JMP на остаток.

Если кто не знает, рисование линий (даже со сглаживанием) - достаточно простая целочисленная математика. Упрощено - вначале готовишь набор коофициентов, потом - бежишь по циклу, инкриментируя счётчики этими коофициентами.

Так вот, развертывание не помогло, а - замедлило. Развернутый цикл не влез в кеш процессора и много времени стало уходить на чтение из оперативки.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации