Полна чудес могучая природа
lexa - 21/Дек/2010 23:07
А в SSE4.1 оказывается есть минимум-максимум для 16-битных целых. 8 штук зараз.
Хреначит 11 гигабайт в секунду, сдается мне что параллелить по ядрам дальше смысла нет, упрешься в память.
И dot-product есть, правда только для float/double.
Чешутся руки забить на владельцев AMD и всего младше Penryn, держите меня...
Comments
Только вот в АМД-шных пока что нет того sse4.1. Так что н
Только вот в АМД-шных пока что нет того sse4.1.
Так что не факт, что в Фотошопе 6 это будет использовано.
да и зачем ? 5-й и так быстр, они наконец-то (если верить написанному на форумах) всё вычислительное переписали с использованием sse2, а не только отдельные фильтры.
А причем тут фотошоп? Я чисто о своем (см. теги). Смотрю на
А причем тут фотошоп?
Я чисто о своем (см. теги). Смотрю на хотспоты, смотрю на SSE-инструкции и думаю.
Я, конечно, эти тестовые примеры еще и в OpenMP заверну, может оказаться, что на 4 горшках оно и без SSE упирается в память, тогда и ладно.
пардон 8-) А это сильно ускорит ? Ну, если можно получит
пардон 8-)
А это сильно ускорит ?
Ну, если можно получить ту же скорость на 2-х ядрах, а не на 4-х, то было бы классно.
Минимум-максимум - ровно вчетверо быстрее. На одном треде.
Минимум-максимум - ровно вчетверо быстрее. На одном треде.
Умножение вектора на матрицу еще не попробовал, но сдается мне что разница будет еще больше: тот код что сейчас есть офигачивает ~300Mb/sec, а причин не упереться в ту же память (т.е. в ~5.5Gb/sec т.к. мы еще и пишем туда) я не вижу.
Ого. Вопрос в том, насколько это ускорит всё преобразование
Ого.
Вопрос в том, насколько это ускорит всё преобразование, там же и другие вычисления.
>> тот код что сейчас есть офигачивает ~300Mb/sec,
Те. 300 метров raw данных в секунду ? А на каком преобразовании ?
Да, там конечно другие вычисления и та же интерполяция - отн
Да, там конечно другие вычисления и та же интерполяция - относительно медленная.
Но 600 миллисекунд там, 250 - сям, глядишь и еще секунду снимем с 20-мегапиксельной картинки. Если без демозаики - а этот режим весьма интересен для всяких просмотрщиков - то я надеюсь в 1.5 секунды для 20-мегапикселей уложиться на все. Это для Кэнона, который медленно распаковывается, с теми же Сонями нет причин не уложиться в полсекунды.
А 300Mb/sec - это цветовое преобразование, на входе тройка R-G-B (или четверка R-G-B-G) и матрица матричного профиля, на выходе - R-G-B в каком-то приличном цветовом пространстве вроде sRGB/gamma 1
Кэнон чем-то ресурсоёмким запакован ?
Кэнон чем-то ресурсоёмким запакован ?
Ну да. Lossles jpeg, да еще и с нетрадиционным layout, <a hr
Ну да. Lossles jpeg, да еще и с нетрадиционным layout, только что обсуждали.
И одним куском, DNG с такой же паковкой - побит на tiles (необязательно, но по факту - очень часто) и можно параллелить по процессорам хотя бы.
<b>>> т.е. в ~5.5Gb/sec <<</b> Это откуда такие данные ?!? и
>> т.е. в ~5.5Gb/sec <<
Это откуда такие данные ?!?
и что это за память такая ?
(или это в битах и для кэша? :-))
Да в-принципе да, может быть и больше можно. Всякие тесты m
Да в-принципе да, может быть и больше можно.
Всякие тесты memory-copy намеривают для DDR3-1600 (трехканальной) в районе 8-9 гигабайт в секунду, это и есть целевое значение.
"8-9 гигабайт в секунду" это
"8-9 гигабайт в секунду"
это же наверное на одном ядре.. чтобы всю псп забить, насколько я помню, нужно всеми ядрами пыхтеть..
Ну формально - 3 канала на
Ну формально - 3 канала на ~11gb/sec (DDR3, 1500 гигагерцiв), итого 33, это на чтение. Как прикинуть влияние задержек - понятия не имею.
А по факту - вот сижу и щупаю, сколько можно нагадить в память зараз.
В-общем, один movntps/movntdq
В-общем, один movntps/movntdq льет примерно 5 гигабайт/сек.
Он же с openmp - 6-6.1 гигабайт/сек. Если зажать число потоков до 4 (у меня 8 ядер: 4 да гипертрединг), то 6.7
Как-то я ожидал большего, если честно. Хотя все равно приятно.
Код, который пишет компилятор - медленнее, примерно 5gb/sec в пике.
что-то маловато.. я думал
что-то маловато.. я думал если захотеть, то на core i7 можно достичь больше 20GiB/s на чтение и запись..
Может там кто-то по рукам кнутом бьёт?
Например можно попробовать два раза тест прогнать, замеряя только время второго (может calloc, но лучше всё таки один разу "вручную" заполнить).. Может там такой оверхед от ОСи - например windows реально выделяет память только под реально используемые страницы, или ещё какой кнут..
Ну вот результат такой
Ну вот результат такой уже:
1) Заполнение массива (1.5 гигабайта) через movntps - ~4.5Gb/sec без OpenMP и 5.8 - в 8 потоков.
2) операция вида
считать 4 float
три dot-product и два blendps
записать 4 float туда же, куда писали
4.8 Gb/sec на одном ядре и до 11.2 - на OpenMP (числом тредов не управляю).
В том смысле, что 100 мегапикселей (по 16 байт на пиксель) за 313 миллисекунд.
Возможно, действительно на 1-м шаге мне выделяют память по страничкам, лениво так. Сейчас добавлю второй проход для шага 1.
Агабля! Второй проход той же
Агабля!
Второй проход той же инициализациями (но другими значениями, чтобы было видно что работает) - 12.3Gb/sec в один поток и 16.7 - во всю дурь.
Во, теперь похоже на правду совсем.
О круто! Вот только всё равно
О круто!
Вот только всё равно хочу больше 20GiB/s, причём на своих 3xDDR3-1333 :)
Кстати, думаю не обязательно прям все значения предварительно инициализировать - можно "прогуляться" с шагом 4KiB, или что-то типа этого.. А может есть что-то ОС-зависимое, но хочется без этого..
Может быть и можно, я
Может быть и можно, я пробовал анроллить и становилось хуже.
Но я пока только учусь. Кроме того, один и тот же _mm_store_ps превращается то в mov, то в mov без кэширования, т.е. у компилятора какой-то свой ум в этом месте.
Вот только всё равно хочу
значит vs2010, core i7 930, 3xDDR3-1333, ht выключен, openmp 4 потока, размер массива - 800MiB - выровнен по 64 байтам, каждый поток пишет/читает по 4 xmm(то есть 64 байта), перед началом всё инициализируется, основной цикл повторяется 16 раз
_mm_stream_pd компилируется в movntpd ~ 17Gb/s
_mm_store_pd компилируется в movapd ~ 12Gb/s
_mm_load_p компилируется в movapd ~ 21.7Gb/s
load_pd - это же чтение
load_pd - это же чтение такое?
Ну да, с префетчем и если регистров хватает, наверное как-то так. 17gb/sec.
Чистое копирование меня интересует постольку-поскольку, хотя вот вместе с конверсией типа, скажем float в short - интересно будет попробовать.
да, load_pd это чтение.. Я
да, load_pd это чтение..
Я видел в тестах памяти SiSoftware Sandra псп памяти около 22Gb/s, и так как запись не дотягивает и до 20, решил проверить и чтение.. В итоге, в тесте Sandra, скорей всего проверяется чтение..
Мне вот интересно, почему у вас на DDR3-1600 примерно такие же результаты по записи, может нужно в биосе частоту памяти установить? Например у меня в биосе явно стоит 1333, а не авто, я по-моему это явно устанавливал.
У меня не 1600, а 1500
У меня не 1600, а 1500 реально. Во всяком случае, оно так пишет про себя при загрузке.
Но, возможно, какие-то другие клоки при этом похуже.
Поднял частоту памяти (и,
Поднял частоту памяти (и, заодно, процессора), процессор стал 3.2, память - 1600.
Запись выросла до 19.2GB/sec (_mm_stream_ps)
Блин, новые горшки объявили,
Блин, новые горшки объявили, которые Sandy Bridge. Всего в два раза больше (в смысле AVX), но памяти - только два канала. То бишь вместо 25Gb/sec полосы - только 17 намеривают.
К концу года обещают 4-канальные, конечно, но ведь столько ждать - это утомиться!
Как-то SSE, в смысле уже AVX,
Как-то SSE, в смысле уже AVX, совсем медленно развивается. Через десять лет после SSE2, они только созрели удвоить размер регистров..
А далеко не всем алгоритмам
А далеко не всем алгоритмам от удвоения регистров так уж полегчает. Скажем, тот же imaging - в вектор влезал пиксель (R,G,B и альфа-канал) - и с пикселем удобно работать. А два пикселя - нафига?
А во внутренностях, при сохранении набора команд, работа постоянно шла: два (теперь вот уже три) порта исполнения, все такое. Регистровые файлы росли, опять же.
Мне вот гораздо больше нравится, что у новых горшков можно (вроде бы! пока всерьез не изучал) о выравнивании гораздо меньше заботиться. То есть старые куски кода, которые грузили unaligned данные - заработают быстрее, даже если их вообще не трогать и не перекомпилировать.
А далеко не всем алгоритмам
Не, ну понятно. Просто например в double векторизовать не всегда очень выгодно (при sse2) - лезть в ассемблер или intrinsics, только из-за двух-кратного ускорения (также учитывая что точность теряется, так как fpu это всё-таки 80бит..), не очень хочется.
Ладно если float..
А вот это кстати по-моему ещё с Core I7 (в смысле не в новейших). Я по-моему даже какой-то тест делал - на Core2 unaligned инструкция чуть ли не в два раза медленней чем aligned, когда на Core I7 скорость точно такая же..
Да, вы кругом правы. И про
Да, вы кругом правы. И про double (про него не думал, мне сейчас не надо) и про unaligned load
Вот кстати gpu в этом плане
Вот кстати gpu в этом плане более православные..
Вот на CPU возможно идёт некий счётный процесс, который грузит все ядра, причём кэши и регистры у него забиты впритык (например тот же gemm), мало того что из-за вклинивания всяких системных и не очень процессов регистры могут тасоваться туда-сюда, так и ещё какая-нибудь сволочь может взять да и сбросить/сожрать весь кэш.. (можно конечно отдавать ядра отдельным процессам, но всё же дёготь есть)
То есть я к тому, что концепция обособленного вычислятора(будь то gpu или larabee), достаточно не плоха. А самое главное - программисты всегда будут сыты ;)
Концепция отличная и, по всей
Концепция отличная и, по всей видимости, для интересных мне приложений (с картинками) будет сильно производительнее на каком-то современном железе.
Но. с этими _mm_... - я в профайлере смотрю на хотспоты и, при условии подходящей организации памяти, пишу буквально десяток инструкций. Или сто.
А с OpenCL/CUDA - нужно довольно большие куски переписывать. Более объемная задача.
Но. с этими _mm_... - я в
Какой профайлер используете? VTune?
Под виндами - VTune, на маке
Под виндами - VTune, на маке - Shark. Но на маке редко теперь работаю.
Кстати, там же ещё есть turbo
Кстати, там же ещё есть turbo boost, так что можно попробовать OpenMP c num_threads(2)
Ну вот получилось писать на 6.7Gb/sec, правда из четырех тре
Ну вот получилось писать на 6.7Gb/sec, правда из четырех тредов. Из одного только пять.
О боже! вот уж воистину - ignorance is bliss это ты с кэшем
О боже!
вот уж воистину - ignorance is bliss
это ты с кэшем работал. убери кэш, и все времена на порядок с лишним ухудшатся.
...можешь потыкаться в гугель с запросами ras/cas, хотя бы.
Какой нафиг кэш, если а) я пишу 600 мегабайт в тесте б) mo
Какой нафиг кэш, если
а) я пишу 600 мегабайт в тесте
б) movntps - он, типа, мимо кэша
Лёша, ты три тезиса связать сумеешь ? вот они: *: Move packe
Лёша, ты три тезиса связать сумеешь ?
вот они:
*: Move packed single-precision floating-point values from xmm to m128 using non-temporal hint.
*: The non-temporal hint is implemented by using a write combining (WC) memory type protocol when writing the data to memory.
*: Write-combining is a limited caching optimization (more often used for RAM on devices such as graphics cards.)
так понятней ? ,-)
// ну и про прочие prefetch & write back тоже не забываем, ага
И че? Думаешь 100 миллионов 16-байтных значений поместятся
И че?
Думаешь 100 миллионов 16-байтных значений поместятся в кэше?
полагаю, что prefetch для того и был придуман, чтобы уменьши
полагаю, что prefetch для того и был придуман, чтобы уменьшить кэш-промахи (а при опр. условиях и вовсе их избежать)... ты же отдаёшь себе отчёт в том, что prefetch выполняется асинхронно ? ...или таки - нет ?
Але, мы кажется <b>запись</b> обсуждали, причем тут prefetch
Але, мы кажется запись обсуждали, причем тут prefetch?
нет, ты изначально рассматривал memory-to-memory copy. (напр
нет, ты изначально рассматривал memory-to-memory copy. (напр. распаковку рава.)
кстати, WC нарушает "все мыслимые" полиси работы с памятью (не гарантирован порядок того и сего, не гарантирована "когерентность" и ты.ды.), так что...
Не, распаковку рава я тут (в этом письме) не обсуждал. Обсуж
Не, распаковку рава я тут (в этом письме) не обсуждал. Обсуждал read-modify-write (туда же), но там не movntps
а всё равно без кэша была бы полная труба... ну, порядок мож
а всё равно без кэша была бы полная труба...
ну, порядок можно было потерять запросто, я думаю.
На read-write - скорее да. По той причине, что prefetch для,
На read-write - скорее да. По той причине, что prefetch для, как минимум, половины элементов достается на халяву.
С префетчем я еще поэкспериментирую, ибо интересно.
На чистый write - из поведения movntps видно, что большой кэш нафиг не нужен при длинных записях.
Если проводить аналогию с диском, то при линейных паттернах тоже не нужен кэш больше чем на дорожку.
Да, то что WC нарушает все подряд - это же отлично, нет вымы
Да, то что WC нарушает все подряд - это же отлично, нет вымывания кэша, нет оверхеда на синхронизацию кэшей в случае multicore. То есть если удается снабдить горшки независимыми данными (а с imaging - это несложно), то только за счастье.
fence только не забывать.
На видеокартах память так же устроена, я привычный.
а кого волнует "вымывание кэша" ? ты его чего, <s>солить</s>
а кого волнует "вымывание кэша" ? ты его чего,
солитьконсервировать собрался ?кэш оптимизирует работу с памятью. через уэш всё (с точки зрения доступа к мэмори) оптимальней происходит. а тем более при последовательной записи/чтении.
Интел пишет нам "Writes to the WC memory type are not cached
Интел пишет нам
"Writes to the WC memory type are not cached in the typical sense of the word cached"
Чем какбэ намекает нам, что у тебя sense какой-то не typical....
тогда уж цитируй дальше: "They are delayed in an internal bu
тогда уж цитируй дальше: "They are delayed in an internal buffer ... If software cares about data being delayed developers
must deliberately empty the WC buffers"
т.е. операция записи асинхронная.
это, знаешь ли, в свою очередь ну ни фига не typical sense of the memory writing ,-)
да, кстати, таки ты выполняется ли у тебя по коду "deliberately empty the WC buffers" ? ...а ты попробуй ,-)
Конечно асинхронная, если писать по 16 байт вместо 64, счаст
Конечно асинхронная, если писать по 16 байт вместо 64, счастья не будет.
Заметим в скобках, что отключение L2/L3, которым ты тут пугаешь, на скорость этой записи вообще не повлияют.
Впрочем, если проинитить странички заранее, а не писать в то
Впрочем, если проинитить странички заранее, а не писать в только что выделенные, то скорость записи становится ближе к ожидаемой: 10-11Gb/sec в один поток и 16-17Gb/sec во все ядра.
Просто _mm_store_ps(куда, чего) в цикле.
А read, три умножения и два blend, write туда-же - 10-11Gb/sec.
ну вот видишь, сам же <s>убедился</s> продемонстрировал, что
ну вот видишь, сам же
убедилсяпродемонстрировал, чтоsizecache does matter :-))а теперь отключи L2/L3 кэш и насладись результатом (и приготовься к тому, что общая производительность системы упадёт на пару порядков... т.е. запасись
попкорномтерпением)Зачем мне его отключать то? Я щупаю реальный перформанс на р
Зачем мне его отключать то? Я щупаю реальный перформанс на реальном таком полуторагигабайтном (уже) working set
а ты отключи, и вопросы отпадут сами собой :-)) кстати, кол
а ты отключи, и вопросы отпадут сами собой :-))
кстати, коль уж кэш не при чём, то каким образом "если проинитить странички заранее, а не писать в только что выделенные, то скорость записи становится ближе к ожидаемой" ?
сам-то как думаешь ? :-))
Не-не, это другое. Я могу взять у системы pinned memory (не
Не-не, это другое.
Я могу взять у системы pinned memory (не факт что мне дадут полтора гига, ну значит гиг) - и тогда скорость сразу будет правильной.
А то что выдают "по умолчанию" - оно вообще никуда не помэплено (может я взял, а использовать не собираюсь) и соответственно при первом обращении в каждую страницу у меня PF.
То есть про кэш ты пишешь - это теоретически правильно, если бы у меня речь шла о мегабайтах т.е. о размерах сравнимых с размерами кэшей, то скорости были бы еще выше.
Собственно, хрен ли, с кэшом сейчас померяю тоже. В смысле, на маленьком working set, мегабайт 6
Меньше чем ожидал, но вот скорости кэшей 2-мегабайтный work
Меньше чем ожидал, но вот скорости кэшей
2-мегабайтный working set - ~20Gb/sec
80к - 28Gb/sec
все на одном ядре.
В несколько потоков параллелить бессмысленно, слишком они мелкие получаются.
Естественно, movaps а не non-temporal
это ж последовательный доступ. в таком режиме кэш оч.эффекти
это ж последовательный доступ.
в таком режиме кэш оч.эффективен. (WB/prefetch асинхронно и параллельно, т.е. как бы на халяву).
кстати, а нафига нужно связываться с этими non-temporal hint ? кто-нибудь профилировал это дело, или так, от балды решили, что "будет лучше" ?
Компилятор (интеловский) считает, что так лучше и ставит их
Компилятор (интеловский) считает, что так лучше и ставит их вместо _mm_store_ps() если в цикле он один. А если два в соседние адреса (типа, поанроллил) - то не ставит.
ну, это он не понял, что по факту там будет последовательная
ну, это он не понял, что по факту там будет последовательная запись...
наверное имеет смысл прагмами ему объяснить, чтобы не шибко умничал.
Ну вот Visual C++ в это место лепит movaps всегда. А профай
Ну вот Visual C++ в это место лепит movaps всегда.
А профайлер (VTune) показывает нам, что movntps на четверть быстрее. Что какбэ намекает нам, что интел то прав.
Кстати, 5.5 гигабайт в секунду на запись уже не пугают? А т
Кстати, 5.5 гигабайт в секунду на запись уже не пугают?
А то я и без всякого SSE научился почти столько получать, на чистых плюсах.
последовательное чтение/запись через кэш-то? - нет, совершен
последовательное чтение/запись через кэш-то? - нет, совершенно не смущает/пугает.
...с памятью как с диском: "seek time" (т.е. ras/cas и сопутствующие латентности) дорогие, зато потом всё быстро. вот кэш и минимизирует эти "сиик таймззз", за счёт чего и приближается к производительности шины.
мммм... оно, кажется, ни фига не "ПОСИКС", но тем не менее,
мммм...
оно, кажется, ни фига не "ПОСИКС", но тем не менее, насколько помню, можно запросить аллокацию с "коммитом", т.е. уже помэпленный кусок.
может, кстати, и даст прирост в производительности.
Я как-то не уверен, как ее можно так запросить, но потом мож
Я как-то не уверен, как ее можно так запросить, но потом можно залочить. Правда если попросил сначала больше присутствующей физической...
ну вот видишь, сам же
Отсыпь травы, а то мне тебя не понять..
Он не увидит этого, это из ЖЖ
Он не увидит этого, это из ЖЖ приехало
(http://alextutubalin.livejournal.com/218527.html#comments)
ну да ладно..
ну да ладно..
Забивать-то зачем? Сделай reference C вариант, и дальше опти
Забивать-то зачем? Сделай reference C вариант, и дальше оптимизируй ассемблер, сколько влезет. На рантайме довольно дешево можно решить, что использовать.
PS: А потом, лет через N, останется убедиться, что С уже не медленнее ручного вариант и расслабиться, качаясь на кресле-качалке у камина :-D
Не, естественно reference C будет, как без него Я скорее пр
Не, естественно reference C будет, как без него
Я скорее про то, что SSE2 варианта я специально делать не буду. Если вдруг появится сам для каких-то кусков, ну отлично тогда.
В автовекторизацию просто скалярного кода на C - я верю слаб
В автовекторизацию просто скалярного кода на C - я верю слабо.
И Интел, судя по всему, тоже не особо верит, впихивая повсюду свои библиотеки.
Ну например GCC кое-что умеет, но в принципе понятно, что ру
Ну например GCC кое-что умеет, но в принципе понятно, что руками можно сделать больше. Ты-бы, кстати, попробовал хохмы ради на libraw, получится-ли что-нибудь, и главное - сколько :)
А библиотеки - ессно ручной вылизанный код для определенных задач будет кошернее. Да и обычные программисты меньше косяков понаделают.
Я пробовал с интеловским компилятором. То, что он делает на
Я пробовал с интеловским компилятором. То, что он делает на хотспотах - мне не нравится, руками можно сильно лучше и с относительно небольшими затратами умственного труда.
Нравится/не нравится выходной ассемблер компилятора - не чис
Нравится/не нравится выходной ассемблер компилятора - не числительное. А вот померять времена выполнения и сравнить - сколько там процентов получится? Интересно ведь. Или это сложно/долго/муторно?
От разрешения генерировать SSE код (что 2, что 4.1) выигрыш
От разрешения генерировать SSE код (что 2, что 4.1) выигрыш какой-то совершенно копеечный, единицы процентов.
Вот от 64-бит - гораздо больше, т.к. куда регистры поюзать компилятор очень быстро находит.
И от смены компилятора с Visual Studio на 12-й интел - тоже заметный выигрыш.
И выигрыш - не на хотспотах. Они, собственно, хотспоты (в большой степени) по той причине, что компилятор там напуган и хороший код сгенерировать не может.
Разрешения SSE мало, тот-же GCC надо отдельным специальным к
Разрешения SSE мало, тот-же GCC надо отдельным специальным ключиком пинать, чтобы автовекторизовывать начал.
> И от смены компилятора с Visual Studio на 12-й интел - тоже заметный выигрыш.
А заметный - это сколько? И интел с автовекторизацией или как?
PS: Я почему столько вопросов задаю - уж очень любопытно выяснить, каких высот достиг прогресс. А у меня таких задач нет.
PPS: А OpenCL версию планируешь? :-)
Я развлекался именно с интелом, профайлер хороший имею на ви
Я развлекался именно с интелом, профайлер хороший имею на винде только.
Выигрыш VS2010/Intel я хорошо помню только для конкретного распаковщика хаффмана, который как раз не параллелится. Процентов 10, кажется. Автовекторизация хотспоты не лечит, не-хотспоты неинтересны.
Что касается OpenCL - да, планирую конечно, но для других мест и не сейчас (и наверное не LibRaw, а другой продукт). Проблема тут в том, что на карту льется гигабайт 5 в секунду и столько же обратно, поэтому нужно там делать сразу здоровый кусок работы, а не хотспоты.
скажем так, автовекторизация на icc работает, но для этого к
скажем так, автовекторизация на icc работает, но для этого код должен быть написан в специальном виде (что по затратам фактически эквивалентно написанию кода на SSE intristics (фактически аналог ассемблера)).
Мы, кажется, о разном. Автовекторизатор вроде как работает
Мы, кажется, о разном.
Автовекторизатор вроде как работает с существующим кодом и разве только просит прагмы расставить.
Я развлекался и особого смысла в результате не увидел, реальные хотспоты все одно придется переписывать, так почему не сразу на псевдоассемблер. Он хоть совместим со всем разумным.
Алексей, я извиняюсь что не
Алексей, я извиняюсь что не по теме, но может подскажете что к чему. Сейчас ось XP SP3, хочу пересесть на семерку, но при этом хочется сохранить текующую ХП в виде виртуальной Оси из под семерки. То есть каким-то образом запаковать XP с софтом, а потом на чистой семерке поставить виртуальную машину, будь то родная от MS или вмваре... и в ней восстановаить прежнюю ХР. Такое возможно? Вообще многим как мне кажется это было бы удобно при переезде на новую Ось - и переезд быстрый, и ничего не потеряно и все работает. Может посоветуете какую лучше виртуалку ставить под семерку, даже если не удасться развернуть старую ХР, то придется новую ставить. Вмваре универсальна и позволяет разворачивать и операционки от MS и от Apple как я понимаю? Заранее спасибо)
Никогда такую задачу не
Никогда такую задачу не решал.
Acronis backup умеет конвертировать backup в виртуальную машину, но я в это место никогда не заглядывал.
Вот кстати, может пригодится
Вот кстати, может пригодится -
http://support.microsoft.com/kb/2280741
Само исправление не пробовал, зато уже видел в деле сам баг:
http://bugreports.qt.nokia.com/browse/QTBUG-11445
Студия влепила movaps на данные выровненные по восьми байтам, а не 16..
Оптимизация программы, С++ под linux
Задача: Таблично задана функция, необходимо вычислить вторую производную методом конечных разностей.
Выбранный подход к решению: Считываем в регистры 3 массива по 4 элемента, один со сдвигом влево (копируем с i-1 элемента: строка 65), второй с нулевым сдвигом (строка 66) и третий со сдвигом вправо (копируем с i+1 элемента: строка 67). Делаем вычисления. Копируем обратно. Программа работает, но sse версия работает много медленнее чем обычное решение.
Подозреваю, что проблема в использовании _mm_set_ps для копирования в регистры (строки 65-67) и организации обратного копирования из регистров (строки 69-71).
Вопрос: Как можно оптимизировать/сделать вменяемыми операции копирования?
Код:
// 1st_SSE.cpp
//
#include
#include
#include
#include
#include
#include
#include
using std::cout;
using std::cin;
using std::endl;
int main()
{
const int N=16*1024+1;
float *d2Ydx2=(float*)malloc(4*sizeof(float));
__m128 Ysse,YRsse,YMsse,YLsse;
__m128 rrs=_mm_set1_ps(-2.0f);
__m128 dX2s=_mm_set1_ps((N*N)/(6.28319f*6.28319f));
__m128 *d2Ydx2SSE=(__m128*) d2Ydx2;
float *Y1=(float*)malloc(N*sizeof(float));
float *Y=(float*)malloc(N*sizeof(float));
float *Y3=(float*)malloc(N*sizeof(float));
__m128 *Y2=(__m128*) Y;
timespec ts_beg, ts_end;
float rr,dX2;
const int SSEN=(N-1)/4;
dX2=(N*N)/(6.28319f*6.28319f);
rr=-2.0f;
//задаем исходную функцию
for (int i=0;i<=N;i++)
{
Y[i]=sin(i*(6.28319f/N));
Y3[i]=0.f;
Y1[i]=0.f;
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_beg);
// решение в лоб
for (int i=1;i<=N-1;i++)
{
Y1[i]=(Y[i-1]+rr*Y[i]+Y[i+1])*dX2;
};
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_end);
float time=(ts_end.tv_sec - ts_beg.tv_sec) + (ts_end.tv_nsec - ts_beg.tv_nsec)/1e9;
cout << "Time required = " << time <
А процессор какой? Почему
А процессор какой? Почему SSE2?
Я бы делал так
1) Выравнивание (если у вас pre-i7 процессор, то это критично)
2) Очевидно что Y[i..i+3] можно прочитать один раз 128-битным чтением, а YLsse/YMsse/YRsse - заполнить из этого регистра через shuffle
3) Зачем store_ps в __m128 переменную, а потом поэлементная запись ее в Y3? Казалось бы, можно прямо в Y3[i] писать?
4) Это самое Y3[i+j] - пишется по 4 элемента на каждом цикле, после чего на следующем - затираются три из них?Я был неправ, у вас же во внешнем цикле i+=4;P.S. Я позволил себе расставить в вашем комментарии теги code.
Еще очевидное улучшение вот
Еще очевидное улучшение вот тут:
- вам для работы нужно 6 элементов, с [i-1] по [i+4]
- но читать их все 6 внутри цикла не надо, вы можете [0] и [1] считать до цикла, потом считывать с [i+1] по [i+4] одним чтением, а [i-1] и [i] брать с первой итерации
- это потребует игр с выравниванием, на 16 байт должно быть выровнено [i+1]