24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
|
1 | |
Битовые утечки при записи данных на диск06.06.2016, 14:42. Показов 5654. Ответов 119
Метки нет (Все метки)
Доброго дня форумчане!
Сорри если оффтоп но... Пишу в консольке на C++ (MSVCE 2010) различные движки по расчетам и тут столкнулся с опасной проблемой. При записи на диск искажаются данные на один бит, где то один раз на 109 - 1011 данных. Бит просто "теряется" (был 1 стал 0 или наоборот) , соответственно данные уже не верны, что приводит к нулю все проделанную работу. Из исследованного: Бит теряется при записи как в поток текстового значения переменных (типа fileout << a[i] << endl; ) Так и при записи в двоичном виде (типа fileout.write(reinterpret_cast<char*>(a),size*sizeof(a[0])); )Замечено, что данные в памяти верные, т.к. были пойманы моменты при повторном выводе из того же массива все данные были записаны корректно. Ошибка не зависит от винчестера на который данные были записаны (были записи на 3 различных винта, один из которых рейд массив). Чаще всего теряется один из старших битов (типа 24-й бит в unsigned long или 24-й в unsigned long long ). Других потерянных бит не замечено.Термин "потерянный" возможно применяю в данном случае не верно. Т.к. заметно искажение только при его инвертировании. Соответственно если был сбой и он вместо 1 записал сбойную 1 - этого я не найду. Система молчит про контроль целостности данных. Винт тоже. У винтов и рейда все показатели в порядке (блоки не сыпятся, SMART в порядке). Сталкивался ли кто с подобным? В чем может быть проблема? В ближайшем будущем хочу переустановить систему и MSVCE 2013. Но не уверен, что система виновата. Кто что подскажет?
1
|
06.06.2016, 14:42 | |
Ответы с готовыми решениями:
119
ClientDataSet, Blob утечки памяти при записи в файл При записи файлов на диск, комптютер выдал ошибку, что данный диск не может дальше использоваться При закачке игры на жесткий диск пишет "Ошибка при записи на диск" При закачке игры на жесткий диск пишет "Ошибка при записи на диск" |
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
|
|
10.06.2016, 10:37 | 21 |
как запустить ее на 12 ч тест? могу прогнать ее на нескольких машинах и посмотреть на результат
1
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
||||||
10.06.2016, 11:52 [ТС] | 22 | |||||
vxg, Спасибо огромное. К сожалению делаю это вручную.
1 запуск и 10 выводов бинарника со сравнением сторонней программой (FC) с эталонным файлом. Затем перезапуск и все по новой. Сейчас подумаю как можно ее сделать в автоматическом режиме. За два дня отловил три ошибки в памяти. (Если результат изменен именно в памяти, можно вторым проходом делать проверку сразу по памяти, добавлю в код.) С измененным кодом увидел, что чаще именно в памяти хранится неверный результат (отличный именно в 24-м бите). Адреса 8-байтовых ячеек: Код
172DB2928 (16) = 0001 0111 0010 1101 1011 0010 1001 0010 1000 (2) 1729E9928 (16) = 0001 0111 0010 1001 1110 1001 1001 0010 1000 (2) 1875D8928 (16) = 0001 1000 0111 0101 1101 1000 1001 0010 1000 (2) Сам измененный код:
0
|
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
|
|
10.06.2016, 11:58 | 23 |
что мешает считывать и сравнивать любое количество раз (например пока не поймает ошибку) в коде аналогичном предложенному здесь Битовые утечки при записи данных на диск
1
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
|
10.06.2016, 12:10 [ТС] | 24 |
vxg, Сейчас как раз этим занимаюсь. Но как уже сказал, если ошибки в памяти, то лучше исключить работу с файлами - медленная операция.
Добавлено через 1 минуту Вселяет оптимизм, что проблема все же может быть в софте, т.к. по железу memtest ошибок не нашел.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
10.06.2016, 17:41 | 26 |
Petrolion, Может быть и ошибка процессора. Я один раз натыкался на похожее. Попробуйте обновить биос/микрокод процессора.
1
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.06.2016, 23:15 | 27 |
Evg, как мне кажется, если бы процессор сбоил, то проблемы были бы хуже. Как минимум, после сбоя, i бы не возращалась к нормальному состоянию.
Petrolion, я не знаю, как точно все устроено, но немного поразмыслил. Скорей всего у Вас битая память. Точнее 1 бит. 24-ый - потому что вы выбрали 64 битный тип данных, из-за выравнивания он всегда будет находится на этой позиции. ECC думаю помог бы в этой ситуации, так как сбой, скорей всего, происходит при записи в этот бит. Если у Вас больше 1 модуля, попробуйте протестировать каждый по отдельности. Если один, то попробуйте найти/купить/попросить другой модуль. Добавлено через 2 минуты Не исключаю, что проблема в контроллере памяти, который, с большой вероятностью, находится в процессоре. Тогда, как и предположил Evg, проблема в нём. Но вероятность очень маленькая.
1
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
||||||
11.06.2016, 11:47 [ТС] | 28 | |||||
Обнаружил неприятное, но сильно понятнее не стало.
"Бесконечный" код для теста был:
Код
Заполнение массива восходящими значениями от определенной величины. Проверка массива на соответствие заполненному (8-16 раз). Очистка массивы нулями. Проверка все ли нули (8-16 раз). Заполнение массива всеми заполненными битами. Проверка всех бит на наличие заполнения (8-16 раз). и все по новой... Esc затем y .Лог пишется параллельно в файл. Обнаружил что если при запуске ошибка возникла в памяти, то она есть уже при всех считываниях (разумеется). Но при этом заполнение этого же массива нулями не показывает наличие сбоя в памяти при заполнении. Так же ведет себя заполнение единицами. Но при втором круге - заполнение восходящими значениями, опять возникает ошибка там же либо в другой ячейке. И так все время. Если же с самого начала тест на возрастающих значениях ошибок не показал, то он его не покажет и через несколько часов. Т.е. есть закономерность при запуске. Теоретически действительно может быть одно из ядер процессора. Только как узнать какое именно? (кол-во я получить могу, но вот номер...) И опять же не без НО. Но почему при заполнении нулями и единицами сбоев нет совсем. Должны быть если это проц. В приложенном файле логи ошибочных и удачных запусков. В первом - кол-во проходов 16 для int k = 1<<24; Во втором проходов 8 для int k = 3<<24; Evg 4 версия мемтеста уже работает с памятью каждым ядром процессора по отдельности (параллельно и последовательно). Т.е. получается, что в данном случае сбой не в памяти, а возможно, в процессоре или в софте при расчете. Тогда почему при том же расчете при проверке, не происходит сбоя в том же самом ядре? Мой результат теста показал, что если ошибка появилась, то она уже есть все время в пределах текущего запуска и массива. vxg можешь попробовать этот код запустить? Или может мой готовый exe файл дать? (На случай если у меня C++ погнал)
0
|
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
|
11.06.2016, 11:58 | 29 |
1
|
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
|
|
11.06.2016, 12:37 | 30 |
Тогда сначала надо привязать поток к процессору (SetThreadAffinityMask), а то он может в любое время перелететь на другое.
Добавлено через 19 минут Тогда как-нибудь бы или узнать физический адрес этого места или хотя бы перезагрузить эту страницу по другому адресу и посмотреть, как будет после этого. Как бы только это сделать простым способом?..
1
|
11.06.2016, 14:16 | 31 |
Для порядку надо ещё и на бинарный код посмотреть. Я в intel'овской системе команд не разбираюсь, но, возможно, кто-то сдюжит на ассемблере целенаправленный тест написать. Тут важным моментом является то, что первый цикл с точки зрения построения кода и его исполнения принципиально отличается от второго и третьего. В первом цикле на каждой итерации изменяется значение в регистре, из которого затем данные попадают в память. Во втором и третьем цикле значения в этом регистре вычисляются вне цикла и внутри цикла уже не модифицируются. И если на какой-то итерации в первом цикле регистр оказался с неправильным значением, то с этого момента все записи в память пойдёт с неправильным значением
Тут уже писали, что если данный фрагмент кода постоянно исполняется на одном и том же ядре, то такое поведение вполне логично В реальности процессор исполняет намного больше, чем написано в этом примере. Тут работа идёт с большим объёмом данных (1 гигабайт). А потому в процессе исполнения циклов постоянно работает механизм вытеснения данных из кэша. При этом кэши первого уровня, насколько я понимаю, находятся на каждом ядре, а кэши второго и третьего уровня общие. При протравливании кэша первого уровня ещё работает механизм когерентности кэшей, чтобы инвалидация кэша распространилась на все ядра. Сам процесс записи непосредственно в память тоже достаточно сложный, т.к. между кэшем и непосредственно планкой памяти куча всяких механизмов. Весь цикл записи занимает много довольно тактов, а потому в процессе исполнения успевает возникать аппаратное прерывание от таймера. В момент перывания неисполненные операции работы с памятью сбрасываются в так называемый подвал (cellar) и их переисполнением занимается операционная система. Правда этот вариант отбрасывается, т.к. в этом случае дефектным было бы значение только по одному адресу в памяти, а не в большом блоке. После прерывания операционная система по каким-то причинам могла неправильно восстановить значение регистра, что так же привело бы к неправильному значению в большом блоке памяти Добавлено через 2 минуты Пардон, тут 4 гигабайта. Если физической памяти меньше, то будут ещё и откачки-подкачки виртуальных страниц, что тоже делается через операционную систему Добавлено через 6 минут Увидел логи, по ходу я словесное описание не правильно понял. Сбой всё-таки единичный (портится значение только в одном адресе памяти). Т.е. варианты с проблемами, вызыванными прерыванием операционной сиситемы, скорее всего отбрасываются. Но странным выглядит то, что сбой происходит примерно по одним и тем же виртуальным адресам. Т.е. тут дело скорее в подсистеме памяти (начиная от кэша и далее), чем в вычислительных узлах процессора Так что для порядку имеет смысл провести эксперимент с привязкой исполнения к конкретному ядру Добавлено через 1 минуту Обнуление и объединичивание блока памяти попробуй выкинуть из теста. По идее это лишний мусор, который только мешает. Так же полезно было бы выкинуть обработку нажатия клавиши и всю печать переделать на printf/fprintf. Это сильно упростит код функции main (на тот случай, если кто-то захочет проанализировать бинарный код). И оставить только одну печать (либо в лог, либо на экран) Добавлено через 2 минуты И проверку делать не по 8 раз, а по одному. Т.е. минимизировать пример, вопсроизводящий проблему Добавлено через 3 минуты И ещё одно наблюдение (правда ни на какие мысли не навело). По адресу 19EA69918 дефект всегда заключается в том, что в 24-м бите имеется единица, но должен быть 0, а по адресу 1A27BC928 ситуация всегда обратная
3
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
||||||
11.06.2016, 16:25 [ТС] | 32 | |||||
Evg, спасибо за детальность. Поправки по ходу. Объем физической памяти 16 гиг. Своп вообще отключен. Процесс идет на одном ядре. Правда не зафиксировал его на определенном, но пока не возникает переполняющих потоков, он с него вроде не слазит. Объем массива для обработки 8 гиг. (unsigned long long). Кэши первого и второго уровней раздельны. Третий уровень общий.
Бит меняет значение с непонятно чего. Возможно при вычислении в момент присвоения (потому и еще два блока обнуления и заполнения). Действительно сейчас хочу уменьшить кол-во проверок до 2-х. Добавил по подсказке nonedark2008 получение номера ядра. Пока не отловил ошибку. Думаю добавить освобождение и повторное выделение памяти под массив. Чтобы спровоцировать ошибки без перезапусков. Так же добавил 4-й блок:
Много лет назад занимался ассемблером на 80286 и 80386, но теперь вряд ли потяну разобрать полученный бинарник даже с облегчениями типа fprinf или malloc . :-(Возможно обнаружение ошибки может заключаться не в обнулении или установке 24 бита, а в том что в процессе ошибки мы ее замечаем. Т.е. если ошибочно бит сбрасывается, но в нем и так 0 то мы ее просто не видим. ("Видишь суслика? - Нет. - А он есть!") и наоборот, при ошибочной установке бита если он и так 1 . Т.о. ошибок может быть и больше.
0
|
11.06.2016, 16:48 | 33 |
Этот пример не соответствует тому, на котором возникала ошибка. Ошибка возникала в цикле
C for (int i = 0; i < n; i++) //Asc tab b[i]=k+i;
1
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
||||||
11.06.2016, 18:53 [ТС] | 34 | |||||
Запустил последний код и погонял его с проца на проц.
Не пойму что с моими лыжами... чего не едут. Вообще взрыв мозга. Ошибки действительно стали появляться чаще, по разным адресам, в разных тестах (кроме всех нулей). Один раз может появиться, при этом во второй проверке ошибки нет. Появились ошибки в битовом заполнении всеми единицами. Вложил ниже лог запуска. С проца на проц пересаживал задачу вручную (через виндовый диспетчер). Запускаемый код:
Вложил откомпилиный у меня на MSVS2010 код в архиве. Может ли кто в 2013 или 2015 его скомпилить и положить. Чтобы запустить мог. Может это система...
1
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
11.06.2016, 19:49 | 35 |
ХЗ где но скорее всего в процессоре. Надо смотреть еррату на конкретную модель камня.
0
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
|
11.06.2016, 20:16 [ТС] | 36 |
А где такое посмотреть? AMD Phenom II X6 1065T
Сейчас друг забросил откомпиленное в MSVS2015. Почти те же самые яйца - вид сбоку. Только стало больше ошибок на массиве заполненном всеми битами. :-( Уже задумываюсь порешить систему.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
11.06.2016, 20:42 | 37 |
Petrolion, Начните с обновления биоса.
Добавлено через 12 минут Например http://developer.amd.com/wordp... Rev_Gd.pdf начиная со стр. 30 Пример от туда, правда не для вашего процессора:
1
|
24 / 24 / 8
Регистрация: 02.02.2016
Сообщений: 135
|
|
11.06.2016, 20:43 [ТС] | 38 |
avgoor, новее для моей матери биоса нет.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
11.06.2016, 20:49 | 39 |
Пичалька. Ну тогда, возможно,
спасет отца русской демократии. Хотя вряд ли.
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
11.06.2016, 22:09 | 40 |
1) Поставить QtCreator с mingw и проверить ошибку в нем.
2) Загрузиться с лайв-CD Дебиана, sudo apt-get install qt-sdk в консольке, опять-же проверить все в QtCreator. Сразу уточняю, лайв ставит новый софт в оперативку, на хард он ничего не пишет.
1
|
11.06.2016, 22:09 | |
11.06.2016, 22:09 | |
Помогаю со студенческими работами здесь
40
Измерить скорость чтения и записи данных на диск Ошибка при записи на диск Ошибки при записи на DVD диск Жесткий диск тормозит при записи на него Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |