LINUX.ORG.RU

Как получить результат целочисленного деления списком?

 , ,


0

1

В своё время немало напрограммировал на ассемблере и непонаслышке знаю, что стандартная целочисленная операция div там даёт в качестве результата и частное от деления, и остаток.

Был немало удивлён тому факту, что такая полезная особенность CISC-архитектуры Intel нигде не используется!

В том же Perl - было бы логично сделать так:

$minutes=78;
($hours,$minutes)=div($minutes,60);
print "Duration: $hours:$minutes\n";

То есть вопрос не совсем в том, что можно написать такую замечательную функцию div, которая выдаст нам нужный список, а в том, что как минимум в такой функции нужно будет один раз делить и один раз умножать, а как прямолинейный максимум - вообще 2 раза делить.

А зачем? Ведь в итоге-то, если речь идёт о целочисленном делении и архитектуре Intel, всё равно будет выполнен тот же div в результате которого будет сразу получено в разных регистрах процессора частное и остаток. Но почему-то уровнями выше «теряется» либо остаток, либо частное от деления...

Может быть, где-то эту проблему уже решили и есть соотв. модуль на CPAN?

★★★★★

Почитай исходники perl и поймёшь, что выигрыш в эти 5 тактов ровно никакой погоды не сделает.

mix_mix ★★★★★
()

ну для С по идее оптимизирущие компиляторы вызывают div один раз, когда требуется и частное и остаток от тех же делимого и делителя

Harald ★★★★★
()
Ответ на: комментарий от Harald

ну для С по идее оптимизирущие компиляторы вызывают div один раз, когда требуется и частное и остаток от тех же делимого и делителя.

Стало интересно проверить это утверждение. Написал простенький код и прогнал его дизасемблером.

int main(int argc, char *argv[])
{
  int y = argc / 153;
  int z = argc % 153;
  return 0;
}

Там вообще не было вызова div. Вместо div вызывается imul.

Dead ★★★★
()
Ответ на: комментарий от Dead

покажи выхлоп дизассемблера что ли, да и y, z должны потом где-то использоваться, иначе компилятор может вообще всю программу до return 0 соптимизировать

Harald ★★★★★
()
Ответ на: комментарий от Harald

Разобрался, дело было в делении на константу. Такое деление заменяется на imul, который в 1.5 раза быстрее. Если подсунуть

 
int a = random();
  int y = argc / a;
  int z = argc % a;
  printf(" %d %d \n",  y, z);

То без оптимизации div вызывается 2 раза, если с -O2 то 1.

Так что вы правы.

Dead ★★★★
()

Что значит нигде не используется? В лиспе, само собой, используется.

anonymous
()

Я реально не могу припомнить, когда бы мне надо было и то и другое одновременно.Городить огород ради 0.0000001% случаев, когда ИРЛ в средней перл-программе из-за неоптимального использования " вместо ' на несколько порядков больше времени теряется?

redgremlin ★★★★★
()

Крутая оптимизация - экономишь пару тактов на делении, зато создается дополнительный список.

Perl убог. Посмотри в ЛNSP truncate и values.

anonymous
()
Ответ на: комментарий от redgremlin

в средней перл-программе из-за неоптимального использования " вместо ' на несколько порядков больше времени теряется

Enjoy your perl

anonymous
()

Перл — это тебе не форт

buddhist ★★★★★
()
Ответ на: комментарий от anonymous

Крутая оптимизация - экономишь пару тактов на делении, зато создается дополнительный список.

Рили, пару тактов, да вас тут целый стак. Это наверное модно быть дауном и балаболить про пару тактов везде, где только можно, да?

anonymous
()
Ответ на: комментарий от anonymous

На Nehalem throughput 7-17 тактов, а что? Подумай сколько уйдет на конструирование списка. А вообще твоя ирония слишком тонка, я не могу понять к чему ты клонишь.

mix_mix ★★★★★
()
Ответ на: комментарий от redgremlin

из-за неоптимального использования " вместо ' на несколько порядков больше времени теряется?

там прямо такая ОГРОМНАЯ разница?

btw, а что лучше "var = $a" или 'var = ' . $a? а если "var1 = $a ; var2 = $b" или 'var1 = ' . $a . ' ; var2 = ' . $b?

Stil ★★★★★
()

Был немало удивлён тому факту, что такая полезная особенность CISC-архитектуры Intel нигде не используется!

Ну в той же сишке используется, в ЛNСПе тоже.

theNamelessOne ★★★★★
()
Ответ на: комментарий от Stil

там прямо такая ОГРОМНАЯ разница?

Огромная-не огромная, но её хоть померить можно (у меня в районе 5-7% получилось). Лишний div же за пределы статпогрешности не выйдет.

btw, а что лучше

Сам выбирай, что тебе важнее - 5% или читаемость :)

redgremlin ★★★★★
()
Ответ на: комментарий от Dead

То без оптимизации div вызывается 2 раза, если с -O2 то 1.

Сдаётся мне, что в перле и близко такого нет.

Хотя показанная Вами оптмизация совершенно очевидна и то, что программы на Си компилируются как раз с использованием div - весьма симптоматично. Не сомневаюсь, что там деление на степень двойки заменяется на shr.

Из всех математических операций div - самая затратная, и выполнять её несколько раз подряд без всяких на тол разумных причин - глупо по-моему.

Да, тем, кто тут насчёт списка прошёлся - я зря конечно назвал так тему и немудрено, что меня неправильно поняли. Смысл в том, чтобы целочисленное деление возвращало два значения: частное и остаток. Как это будет реализовано на практике - совершенно неважно. Можно передавать две ссылки на переменные, можно возвращать частное как результат выполнения функции и опционально записывать остаток по ссылке на переменную.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

Огромная-не огромная, но её хоть померить можно (у меня в районе 5-7% получилось).

Я оптимально использую кавычки, поэтому могу уже оптимизировать на уровне div'ов :)

DRVTiny ★★★★★
() автор топика

В сортах пёрла не разбираюсь (надо внутрь смотреть), но Math/BigInt: $i->bdiv(BINT) return (BINT,BINT) division (quo,rem) just quo if sc .

anonymous
()
Ответ на: комментарий от mix_mix

На Nehalem throughput 7-17 тактов, а что?

Ну вопервых 7 у тебя ~никогда не будет. Во вторых throughput? рили? на перле?

Во вторых выйграет он вообще в районе нуля, но это не важно. Говори «весь выигрыш от сего действа нивелирует ущербность перловской конструкции, в которой ты собрался отдавать результат».

Подумай сколько уйдет на конструирование списка.

А причем тут список - ты сказал «выйграешь эти 5тактов», ты не говорил «по сравнению с перлом». Ты выйграешь не 5тактов. Сколько там и куда уйдёт это не важно.

А вообще твоя ирония слишком тонка, я не могу понять к чему ты клонишь.

Я ни к чему не клоню. Я против балабольства про такты.

Зачем курлыкать про 5тактов, если это нихрена не 5тактов, если ты мог спокойно сказать так, как я написал выше. И тебе не пришлось съезжать на «подумай сколько бла-бла», типа даже если не 5тактов, то всё ровно меньше.

anonymous
()
Ответ на: комментарий от anonymous

Какая именно лалка порвалась?

anonymous
()
Ответ на: комментарий от anonymous

весь выигрыш от сего действа нивелирует ущербность перловской конструкции, в которой ты собрался отдавать результат

this

Понятно, же о чем речь. В чем смысл спора тогда? Еще 100 комментариев будем такты считать?

Капча «platinum pertics» намекает.

anonymous
()

С синусом и косинусом такая же ситуация, их можно одной командой посчитать.

anonymous
()
Ответ на: комментарий от anonymous

Понятно, же о чем речь. В чем смысл спора тогда? Еще 100 комментариев будем такты считать?

Такие балаболы уродуют психику зелёных. Т.е. если человек поверит в эти «а чё там пара тактов», то он становится просто не способен к программированию.

А потом получается так, что у пацана там поиск catch на глубину 100, парой тысячи вызовов фри в котором минимум один спинлок в каждом - выполняются пару тактов. Или пхп array стоит «пару тактов». Пацана на всё отвечают, - «да что там пару тактов», «пару тактов», «пару тактов».

Пацаны начинают верить в то, что всё говно решается «парой тактов». Кидаются «парой тактов» через каждое слово.

Этот пацан хоть «5тактов» написал, рядовой же ушлёпок написал «пара тактов» по заветам предков, как собственно сделал анонимус выше.

Это тотальные ублюдки, которые достойны тотальной аннигиляции.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.