Uncle Vёder Опубликовано 8 апреля, 2015 Жалоба Share Опубликовано 8 апреля, 2015 Разница между видео в скриншотахДля этого есть замечательный сервис:http://screenshotcomparison.com/comparison/121009 http://screenshotcomparison.com/comparison/121011 Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Daniel5555 Опубликовано 8 апреля, 2015 Автор Жалоба Share Опубликовано 8 апреля, 2015 Разница между видео в скриншотахДля этого есть замечательный сервис:http://screenshotcomparison.com/comparison/121009 http://screenshotcomparison.com/comparison/121011 Спасибо, не знал о нем) Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Black Cat Опубликовано 8 апреля, 2015 Жалоба Share Опубликовано 8 апреля, 2015 В твоем варианте result = (array[threadIdx.x] > 10)*(...) + (!(array[threadIdx.x] > 10))*(...) произойдет тоже самое. Все ядра выполнят все инструкции, просто они выполнят умножение на ноль в первой или во второй части. Разве в гпу нет оптимизации умножения? ессли один из множителей 0 то второй не вычисляется? Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Daniel5555 Опубликовано 8 апреля, 2015 Автор Жалоба Share Опубликовано 8 апреля, 2015 Разве в гпу нет оптимизации умножения? ессли один из множителей 0 то второй не вычисляется? Что такое "оптимизация умножения"? Если процессор встречает переменную равную нулю, которую нужно умножить на другую переменную, он просто выполнит умножение. Он не проверяет равна она нулю или нет, а ALU все равно, на что умножать, это операция занимает одинаковое время, независимо от значений переменных. Компилятор если видит, что часть кода не может быть исполнена, вроде if (false) { ... } , скорее всего, уберет целиком блок и выставит warning. Еще если есть выражение вида if (condition1 and (condition2 or (getCondition3())) { ... } , то скомпилированный код не будет исполнять "(condition2 or (getCondition3())" если condition1 равно false, но это зависит от настроек оптимизации. В коде рекомендуется использовать поменьше if-else, потому что это позволяет избежать потери времени в случае неверного предсказания того, какой блок будет исполняться (из-за досрочного исполнения инструкций, это происходит в обычных процессорах) и это иногда позволяет немного уменьшить размер кода, если это критично. Но это почти никак не влияет на проблему, которую я описал. Для видеокарт в одном блоке все ядра вынуждены выполнять одну и ту же инструкцию. Разница только в том, имеет ли ценность ее результат, и в качестве переменных используются локальные переменные на уровне ядра. Еще имеется небольшая задержка для изменения контекста ядра (при переходе из if в else), но она не должна играть роли на современных видеокартах. Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Black Cat Опубликовано 9 апреля, 2015 Жалоба Share Опубликовано 9 апреля, 2015 , то скомпилированный код не будет исполнять "(condition2 or (getCondition3())" если condition1 равно false, но это зависит от настроек оптимизации.Да похоже с оптимизацией накосячил гдето в подсознании обобщив логическую оптимизацию до арифмитической. Но это не отменяет тот факт, что через такое умножение можно сделать неоптимальное ветвление :) Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Daniel5555 Опубликовано 9 апреля, 2015 Автор Жалоба Share Опубликовано 9 апреля, 2015 , то скомпилированный код не будет исполнять "(condition2 or (getCondition3())" если condition1 равно false, но это зависит от настроек оптимизации.Да похоже с оптимизацией накосячил гдето в подсознании обобщив логическую оптимизацию до арифмитической. Но это не отменяет тот факт, что через такое умножение можно сделать неоптимальное ветвление :) Окей, только я, на всякий случай, уточню две вещи: 1. Оптимизацию делает компилятор, а не процессор. 2. Когда речь идет о простом коде, типа if (condition1 and (condition2 or condition3)) { ... } в таком случае, чаще всего, скомпилированный код такой, что (condition2 or condition3) исполняется всегда. Это происходит ради того, чтобы избежать все тех же неверных предсказаний. Если сделать отдельную оценку condition1 и переход на позицию после блока if в случае если condition1 равен falsе, то в итоге у нас получается, по сути, два блока if, которые будут видны в ассемблерe. Так как все процессоры сейчас преисполняют инструкции, то оптимальнее произвести оценку всех переменных, чем по отдельности condition1 и затем (condition2 or condition3), и получить сильную задержку в случае неверного предсказания результата оценки condition1. Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Black Cat Опубликовано 10 апреля, 2015 Жалоба Share Опубликовано 10 апреля, 2015 Так как все процессоры сейчас преисполняют инструкции, то оптимальнее произвести оценку всех переменных, чем по отдельности condition1 и затем (condition2 or condition3), и получить сильную задержку в случае неверного предсказания результата оценки condition1.Это не всегда можно сделать. Пример: if(p && p->field) Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Daniel5555 Опубликовано 13 апреля, 2015 Автор Жалоба Share Опубликовано 13 апреля, 2015 Так как все процессоры сейчас преисполняют инструкции, то оптимальнее произвести оценку всех переменных, чем по отдельности condition1 и затем (condition2 or condition3), и получить сильную задержку в случае неверного предсказания результата оценки condition1.Это не всегда можно сделать. Пример:if(p && p->field) Я думаю, что это можно сделать технически, но это не имеет смысла в конктексте стандартов и современных операционных систем. Нормальный компилятор, конечно, будет оценивать по отдельности переменные в выражениях такого типа. Некоторые процессоры позволяют исполнять на себе код с включенным branch prediction и выключенным MMU. В таком случае, если компилятор оценит обе переменные, то это не вызовет segmentation fault :) Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Black Cat Опубликовано 14 апреля, 2015 Жалоба Share Опубликовано 14 апреля, 2015 Я думаю, что это можно сделать технически, но это не имеет смысла в конктексте стандартов и современных операционных систем. Нормальный компилятор, конечно, будет оценивать по отдельности переменные в выражениях такого типа. В стандарте С++ заявлено что правое выражение не вычисляется если левое ложно, что имеет смысл так позволяет не разбивать 1 проверку в несколько вложенных условий. Гарантированное же вычисление особых плюшек не дает Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Daniel5555 Опубликовано 14 апреля, 2015 Автор Жалоба Share Опубликовано 14 апреля, 2015 Я думаю, что это можно сделать технически, но это не имеет смысла в конктексте стандартов и современных операционных систем. Нормальный компилятор, конечно, будет оценивать по отдельности переменные в выражениях такого типа. В стандарте С++ заявлено что правое выражение не вычисляется если левое ложно, что имеет смысл так позволяет не разбивать 1 проверку в несколько вложенных условий. Гарантированное же вычисление особых плюшек не дает Ты что-то все путаешь. Если применять со 100% соответствием C++ (и C) стандарты, то во всех проверках, где более одного условия, будет несколько инструкций типа JE на уровне ассемблера. То есть, if (condition1 and condition2) { ... эквивалентно if (condition1) { if (condition2) { ... в ассемблере всегда. Это выглядит приблизительно так: cmpq $0, -8(%rbp) je .L2 movq -8(%rbp), %rax movl (%rax), %eax cmpl $5, %eax jle .L2 Но компиляторы (в том числе gcc) не всегда это делают, чтобы избежать неверных предсказаний на каждой развилке. Эффект от неверного предсказания чувствительный. Если условие оценивается пару раз в коде - то да, конечно его не заметишь, но если это происходит миллионы раз и с достаточным количеством неверных предсказаний, то ситуация уже будет совсем другой. Вот здесь компилятор провел оптимизацию в обход стандарта: http://stackoverflow.com/questions/7355414/short-circuiting-on-boolean-operands-without-side-effects Что касается моего предыдущего поста - есть особо одаренные компиляторы, а так же процессоры, которые позволяют это делать постоянно, в обход не только стандарта C, но и норм архитектуры. Цитата Ссылка на комментарий Поделиться на другие сайты More sharing options...
Рекомендуемые сообщения
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.